func TestKeyInitFailure(t *testing.T) { msg, err := Create("*****@*****.**", false, "", "", Strict, hashchain.TestEntry, cipher.RandReader) if err != nil { t.Fatal(err) } // invalid times _, _, _, err = msg.KeyInit(0, 0, 0, false, "mute.berlin", "", "", cipher.RandReader) if err != ErrInvalidTimes { t.Error("should fail") } _, _, _, err = msg.KeyInit(0, 1, 0, false, "mute.berlin", "", "", cipher.RandReader) if err != ErrExpired { t.Error("should fail") } _, _, _, err = msg.KeyInit(0, uint64(times.OneYearLater()), 0, false, "mute.berlin", "", "", cipher.RandReader) if err != ErrFuture { t.Fatal(err) } // rand fail _, _, _, err = msg.KeyInit(0, uint64(times.NinetyDaysLater()), 0, false, "mute.berlin", "", "", cipher.RandFail) if err == nil { t.Error("should fail") } // decode failure msg.UIDContent.SIGKEY.HASH = "!" _, _, _, err = msg.KeyInit(0, uint64(times.NinetyDaysLater()), 0, false, "mute.berlin", "", "", cipher.RandReader) if err == nil { t.Error("should fail") } }
// Create creates a new UID message for the given userID and self-signs it. // It automatically creates all necessary keys. If sigescrow is true, an // escrow key is included in the created UID message. // Necessary randomness is read from rand. func Create( userID string, sigescrow bool, mixaddress, nymaddress string, pfsPreference PFSPreference, lastEntry string, rand io.Reader, ) (*Message, error) { var msg Message var err error // check user ID (identity) if err := identity.IsMapped(userID); err != nil { return nil, log.Error(err) } msg.UIDContent.VERSION = ProtocolVersion msg.UIDContent.MSGCOUNT = 0 // this is the first UIDMessage msg.UIDContent.NOTAFTER = uint64(times.OneYearLater()) // TODO: make this settable! msg.UIDContent.NOTBEFORE = 0 // TODO: make this settable if pfsPreference == Optional { msg.UIDContent.MIXADDRESS = mixaddress msg.UIDContent.NYMADDRESS = nymaddress } else { msg.UIDContent.MIXADDRESS = "" msg.UIDContent.NYMADDRESS = "" } msg.UIDContent.IDENTITY = userID if err = msg.UIDContent.SIGKEY.initSigKey(rand); err != nil { return nil, err } msg.UIDContent.PUBKEYS = make([]KeyEntry, 1) if err := msg.UIDContent.PUBKEYS[0].InitDHKey(rand); err != nil { return nil, err } if sigescrow { msg.UIDContent.SIGESCROW = new(KeyEntry) if err = msg.UIDContent.SIGESCROW.initSigKey(rand); err != nil { return nil, err } } // make sure LASTENTRY is parseable for a non-keyserver localpart. // For keyservers the LASTENTRY can be empty, iff this is the first entry // in the hashchain. lp, domain, _ := identity.Split(msg.UIDContent.IDENTITY) if lp != "keyserver" { if _, _, _, _, _, _, err := hashchain.SplitEntry(lastEntry); err != nil { return nil, err } } msg.UIDContent.LASTENTRY = lastEntry // set REPOURIS to the domain of UIDContent.IDENTITY // TODO: support different KeyInit repository configurations msg.UIDContent.REPOURIS = []string{domain} msg.UIDContent.PREFERENCES.FORWARDSEC = pfsPreference.String() msg.UIDContent.PREFERENCES.CIPHERSUITES = []string{DefaultCiphersuite} // TODO: CHAINLINK (later protocol version) // theses signatures are always empty for messages the first UIDMessage msg.ESCROWSIGNATURE = "" msg.USERSIGNATURE = "" selfsig := msg.UIDContent.SIGKEY.ed25519Key.Sign(msg.UIDContent.JSON()) msg.SELFSIGNATURE = base64.Encode(selfsig) // TODO: LINKAUTHORITY return &msg, nil }
func TestAccount(t *testing.T) { tmpdir, msgDB, err := createDB() if err != nil { t.Fatal(err) } defer os.RemoveAll(tmpdir) defer msgDB.Close() a := "*****@*****.**" b := "*****@*****.**" if err := msgDB.AddNym(a, a, "Alice"); err != nil { t.Fatal(err) } if err := msgDB.AddContact(a, b, b, "Bob", WhiteList); err != nil { t.Fatal(err) } // add acounts _, privkey1, err := ed25519.GenerateKey(cipher.RandReader) if err != nil { t.Fatal(err) } _, privkey2, err := ed25519.GenerateKey(cipher.RandReader) if err != nil { t.Fatal(err) } server1 := "accounts001.mute.berlin" server2 := "accounts002.mute.berlin" var secret1 [64]byte var secret2 [64]byte if _, err := io.ReadFull(cipher.RandReader, secret1[:]); err != nil { t.Fatal(err) } if _, err := io.ReadFull(cipher.RandReader, secret2[:]); err != nil { t.Fatal(err) } err = msgDB.AddAccount(a, "", privkey1, server1, &secret1, def.MinMinDelay, def.MinMaxDelay) if err != nil { t.Fatal(err) } contacts, err := msgDB.GetAccounts(a) if err != nil { t.Fatal(err) } if len(contacts) != 1 { t.Error("len(contacts) != 1") } else { if contacts[0] != "" { t.Error("contacts[0] != \"\"") } } err = msgDB.AddAccount(a, b, privkey2, server2, &secret2, def.MinMinDelay, def.MinMaxDelay) if err != nil { t.Fatal(err) } // set account time now := times.Now() d90 := times.NinetyDaysLater() d365 := times.OneYearLater() if err := msgDB.SetAccountTime(a, "", d90); err != nil { t.Fatal(err) } if err := msgDB.SetAccountTime(a, b, d365); err != nil { t.Fatal(err) } if err := msgDB.SetAccountLastMsg(a, b, now); err != nil { t.Fatal(err) } // get account pk1, srv1, scrt1, minDelay, maxDelay, lastTime1, err := msgDB.GetAccount(a, "") if err != nil { t.Fatal(err) } if !bytes.Equal(pk1[:], privkey1[:]) { t.Error("pk1 != privkey1") } if srv1 != server1 { t.Error("srv1 != server1") } if !bytes.Equal(scrt1[:], secret1[:]) { t.Error("scrt1 != secret1") } if minDelay != def.MinMinDelay { t.Error("minDelay != def.MinMinDelay") } if maxDelay != def.MinMaxDelay { t.Error("maxDelay != def.MinMaxDelay") } if lastTime1 != 0 { t.Error("lastTime1 != 0") } pk2, srv2, scrt2, _, _, lastTime2, err := msgDB.GetAccount(a, b) if err != nil { t.Fatal(err) } if !bytes.Equal(pk2[:], privkey2[:]) { t.Error("pk2 != privkey2") } if srv2 != server2 { t.Error("srv2 != server2") } if !bytes.Equal(scrt2[:], secret2[:]) { t.Error("scrt2 != secret2") } if lastTime2 != now { t.Error("lastTime2 != now") } // get accounts contacts, err = msgDB.GetAccounts(a) if err != nil { t.Fatal(err) } if len(contacts) != 2 { t.Error("len(contacts) != 2") } else { if contacts[0] != "" { t.Error("contacts[0] != \"\"") } if contacts[1] != b { t.Error("contacts[1] != b") } } // get account time t1, err := msgDB.GetAccountTime(a, "") if err != nil { t.Fatal(err) } if t1 != d90 { t.Error("t1 != d90") } t2, err := msgDB.GetAccountTime(a, b) if err != nil { t.Fatal(err) } if t2 != d365 { t.Error("t2 != d365") } }