RC-7
release-tag / release-image (push) Failing after 2m44s

This commit is contained in:
2026-08-11 16:58:07 +02:00
parent 185ccf1101
commit bcfbef390f
44 changed files with 4778 additions and 172 deletions
+46 -3
View File
@@ -41,8 +41,15 @@ type identityFile struct {
PrivateJWK privateJWK `json:"privateJwk"`
}
const identityKDFIterations = 250000
type encryptedIdentity struct {
Version int `json:"version"`
Format string `json:"format,omitempty"`
ClientID string `json:"clientId,omitempty"`
KDF string `json:"kdf,omitempty"`
Iterations int `json:"iterations,omitempty"`
Cipher string `json:"cipher,omitempty"`
Salt string `json:"salt"`
IV string `json:"iv"`
Ciphertext string `json:"ciphertext"`
@@ -161,6 +168,15 @@ func readIdentityImport(path, passphrase string) (identityFile, error) {
if err := json.Unmarshal(b, &enc); err != nil {
return identityFile{}, err
}
if enc.Format != "" && enc.Format != "neuralhunt-identity-export" {
return identityFile{}, errors.New("unsupported identity export format")
}
if enc.KDF != "" && enc.KDF != "PBKDF2-HMAC-SHA256" {
return identityFile{}, errors.New("unsupported identity KDF")
}
if enc.Cipher != "" && enc.Cipher != "AES-256-GCM" {
return identityFile{}, errors.New("unsupported identity cipher")
}
salt, err := rawURL.DecodeString(enc.Salt)
if err != nil {
return identityFile{}, err
@@ -173,7 +189,14 @@ func readIdentityImport(path, passphrase string) (identityFile, error) {
if err != nil {
return identityFile{}, err
}
key := pbkdf2SHA256([]byte(passphrase), salt, 250000, 32)
iterations := enc.Iterations
if iterations == 0 {
iterations = identityKDFIterations // compatibility with v1 exports
}
if iterations < 100000 || iterations > 2000000 {
return identityFile{}, errors.New("unsupported identity KDF iteration count")
}
key := pbkdf2SHA256([]byte(passphrase), salt, iterations, 32)
block, err := aes.NewCipher(key)
if err != nil {
return identityFile{}, err
@@ -193,6 +216,15 @@ func readIdentityImport(path, passphrase string) (identityFile, error) {
if _, err := privateKeyFromIdentity(id); err != nil {
return identityFile{}, err
}
if enc.ClientID != "" {
cid, err := auth.ClientID(id.PublicJWK)
if err != nil {
return identityFile{}, err
}
if cid != enc.ClientID {
return identityFile{}, errors.New("identity export client ID mismatch")
}
}
return id, nil
}
@@ -200,6 +232,9 @@ func exportBrowserIdentity(path, passphrase string, id identityFile) error {
if passphrase == "" {
return errors.New("export requires --passphrase or NEURALHUNT_IDENTITY_PASSPHRASE")
}
if len(passphrase) < 12 {
return errors.New("identity export passphrase must be at least 12 characters")
}
plain, err := json.Marshal(id)
if err != nil {
return err
@@ -212,7 +247,7 @@ func exportBrowserIdentity(path, passphrase string, id identityFile) error {
if _, err := rand.Read(iv); err != nil {
return err
}
key := pbkdf2SHA256([]byte(passphrase), salt, 250000, 32)
key := pbkdf2SHA256([]byte(passphrase), salt, identityKDFIterations, 32)
block, err := aes.NewCipher(key)
if err != nil {
return err
@@ -222,7 +257,15 @@ func exportBrowserIdentity(path, passphrase string, id identityFile) error {
return err
}
ct := gcm.Seal(nil, iv, plain, nil)
enc := encryptedIdentity{Version: 1, Salt: rawURL.EncodeToString(salt), IV: rawURL.EncodeToString(iv), Ciphertext: rawURL.EncodeToString(ct)}
cid, err := auth.ClientID(id.PublicJWK)
if err != nil {
return err
}
enc := encryptedIdentity{
Version: 1, Format: "neuralhunt-identity-export", ClientID: cid,
KDF: "PBKDF2-HMAC-SHA256", Iterations: identityKDFIterations, Cipher: "AES-256-GCM",
Salt: rawURL.EncodeToString(salt), IV: rawURL.EncodeToString(iv), Ciphertext: rawURL.EncodeToString(ct),
}
b, err := json.MarshalIndent(enc, "", " ")
if err != nil {
return err