// Verify verifies that the KeyInit is valid and contains a valid ECDHE25519 // key. func (ki *KeyInit) Verify(keyInitRepositoryURIs []string, sigPubKey string) error { // The REPOURI points to this KeyInit Repository if !util.ContainsString(keyInitRepositoryURIs, ki.Contents.REPOURI) { log.Error(ErrRepoURI) return ErrRepoURI } // verify that SESSIONANCHORHASH matches decrypted SESSIONANCHOR sa, err := ki.SessionAnchor(sigPubKey) if err != nil { return err } // get KeyEntry message from SessionAnchor ke, err := sa.KeyEntry("ECDHE25519") if err != nil { return err } // verify KeyEntry message if err := ke.Verify(); err != nil { return err } // NOTAFTER and NOTBEFORE are valid if ki.Contents.NOTBEFORE >= ki.Contents.NOTAFTER { log.Error(ErrInvalidTimes) return ErrInvalidTimes } // not expired if ki.Contents.NOTAFTER < uint64(times.Now()) { log.Error(ErrExpired) return ErrExpired } // SIGNATURE was made with UIDMessage.UIDContent.SIGKEY over Contents var ed25519Key cipher.Ed25519Key sig, err := base64.Decode(ki.SIGNATURE) if err != nil { return err } pubKey, err := base64.Decode(sigPubKey) if err != nil { return err } // create ed25519 key ed25519Key.SetPublicKey(pubKey) // verify self-signature if !ed25519Key.Verify(ki.Contents.json(), sig) { log.Error(ErrInvalidKeyInitSig) return ErrInvalidKeyInitSig } return nil }
// Get returns the cached JSON-RPC client and capabilities for the given // domain and makes sure that the requiredMethod is supported. If no client // has been cached, the cache is filled using the Set method with the given // domain, port, altHost, and homedir parameters. func (c *Cache) Get( domain, port, altHost, homedir, requiredMethod string, ) (*jsonclient.URLClient, *capabilities.Capabilities, error) { // check/set cache caps := c.capabilities[domain] if caps == nil { if err := c.Set(domain, port, altHost, homedir); err != nil { return nil, nil, err } } caps = c.capabilities[domain] // check requiredMethod if !util.ContainsString(caps.METHODS, requiredMethod) { return nil, nil, log.Errorf("cache: key server %s does not support %s method", domain, requiredMethod) } // return client and capabilities from cache client := c.clients[domain] if client == nil { panic(log.Criticalf("cache: key server client for domain %s undefined", domain)) } return client, caps, nil }
// Vacuum executes VACUUM command in db. If autoVacuumMode is not nil and // different from the current one, the auto_vacuum mode is changed before // VACUUM is executed. func Vacuum(db *sql.DB, autoVacuumMode string) error { if autoVacuumMode != "" { if !util.ContainsString(autoVacuumModes, autoVacuumMode) { return log.Errorf("encdb: unknown auto_vacuum mode: %s", autoVacuumMode) } var av int64 err := db.QueryRow("PRAGMA auto_vacuum;").Scan(&av) if err != nil { return err } currentMode := autoVacuumModes[av] if currentMode != autoVacuumMode { _, err = db.Exec(fmt.Sprintf("PRAGMA auto_vacuum = %s;", autoVacuumMode)) if err != nil { return err } } } _, err := db.Exec("VACUUM;") if err != nil { return log.Error(err) } return nil }
func TestPrivateUID(t *testing.T) { tmpdir, keyDB, err := createDB() if err != nil { t.Fatal(err) } defer os.RemoveAll(tmpdir) defer keyDB.Close() alice, err := uid.Create("*****@*****.**", false, "", "", uid.Strict, hashchain.TestEntry, cipher.RandReader) if err != nil { t.Fatal(err) } bob, err := uid.Create("*****@*****.**", false, "", "", uid.Strict, hashchain.TestEntry, cipher.RandReader) if err != nil { t.Fatal(err) } if err := keyDB.AddPrivateUID(alice); err != nil { t.Fatal(err) } if err := keyDB.AddPrivateUID(bob); err != nil { t.Fatal(err) } identities, err := keyDB.GetPrivateIdentities() if err != nil { t.Fatal(err) } if len(identities) != 2 { t.Error("wrong number of identities") } if !util.ContainsString(identities, "*****@*****.**") { t.Error("alice missing from identities") } if !util.ContainsString(identities, "*****@*****.**") { t.Error("bob missing from identities") } identities, err = keyDB.GetPrivateIdentitiesForDomain("mute.berlin") if err != nil { t.Fatal(err) } if len(identities) != 1 { t.Error("wrong number of identities") } if !util.ContainsString(identities, "*****@*****.**") { t.Error("alice missing from identities") } a, _, err := keyDB.GetPrivateUID("*****@*****.**", true) if err != nil { t.Fatal(err) } b, _, err := keyDB.GetPrivateUID("*****@*****.**", true) if err != nil { t.Fatal(err) } if a.PrivateEncKey() != alice.PrivateEncKey() { t.Error("PrivateEncKeys differ") } if a.PrivateSigKey() != alice.PrivateSigKey() { t.Error("PrivateSigKeys differ") } if b.SigPubKey() != bob.SigPubKey() { t.Error("SigPubKeys differ") } key, err := cipher.Ed25519Generate(cipher.RandReader) if err != nil { t.Fatal(err) } // encrypt _, _, UIDMessageEncrypted := alice.Encrypt() // create reply reply := uid.CreateReply(UIDMessageEncrypted, "", 0, key) if err := keyDB.AddPrivateUIDReply(alice, reply); err != nil { t.Fatal(err) } if err := keyDB.DelPrivateUID(alice); err != nil { t.Fatal(err) } _, _, err = keyDB.GetPrivateUID("*****@*****.**", false) if err == nil { t.Error("should fail") } }