Example #1
0
// 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
	}
}
Example #2
0
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
}