// GetPrivateUID gets a private uid for identity from keyDB. // // TODO: get all UID messages for given identity which are not expired. func (keyDB *KeyDB) GetPrivateUID( identity string, withPrivkeys bool, ) (*uid.Message, *uid.MessageReply, error) { var ( uidJSON string sigPrivKey string encPrivKey string replyJSON string ) err := keyDB.getPrivateUIDQuery.QueryRow(identity).Scan(&uidJSON, &sigPrivKey, &encPrivKey, &replyJSON) switch { case err == sql.ErrNoRows: return nil, nil, log.Errorf("keydb: no privkey for nym '%s' found", identity) case err != nil: return nil, nil, log.Error(err) default: msg, err := uid.NewJSON(uidJSON) if err != nil { return nil, nil, err } if err := msg.VerifySelfSig(); err != nil { // if this fails something is seriously wrong return nil, nil, log.Error(err) } if withPrivkeys { if err := msg.SetPrivateSigKey(sigPrivKey); err != nil { return nil, nil, err } if err := msg.SetPrivateEncKey(encPrivKey); err != nil { return nil, nil, err } } var msgReply *uid.MessageReply if replyJSON != "" { msgReply, err = uid.NewJSONReply(replyJSON) if err != nil { return nil, nil, err } } return msg, msgReply, nil } }
func (ce *CryptEngine) registerOrUpdate( pseudonym, token, command, verb string, ) error { // map pseudonym id, domain, err := identity.MapPlus(pseudonym) if err != nil { return err } // TODO: check token? // get UID from keyDB msg, messageReply, err := ce.keyDB.GetPrivateUID(id, false) if err != nil { return err } if messageReply != nil { return log.Errorf("cryptengine: UID has already been %s", verb) } // get JSON-RPC client and capabilities client, caps, err := ce.cache.Get(domain, ce.keydPort, ce.keydHost, ce.homedir, "KeyRepository."+command) if err != nil { return err } // register/update UID with key server content := make(map[string]interface{}) content["UIDMessage"] = msg content["Token"] = token reply, err := client.JSONRPCRequest("KeyRepository."+command, content) if err != nil { return err } rep, ok := reply["UIDMessageReply"].(map[string]interface{}) if !ok { return log.Errorf("cryptengine: %s reply has the wrong type", command) } // marshal the unstructured UIDMessageReply into a JSON byte array jsn, err := json.Marshal(rep) if err != nil { return err } // unmarshal the JSON byte array back into a UIDMessageReply msgReply, err := uid.NewJSONReply(string(jsn)) if err != nil { return err } // store reply first to have proof, if the key server is cheating if err := ce.keyDB.AddPrivateUIDReply(msg, msgReply); err != nil { return err } // verify reply // TODO: keyserver can return more than one SIGPUBKEY if err := msgReply.VerifySrvSig(msg, caps.SIGPUBKEYS[0]); err != nil { return err } log.Infof("nym '%s' %s successfully", id, verb) return nil }