+/**
+ * Obtain the ECC key associated with a ego.
+ *
+ * @param ego the ego
+ * @return associated ECC key, valid as long as the ego is valid
+ */
+const struct GNUNET_CRYPTO_EcdsaPrivateKey *
+GNUNET_IDENTITY_ego_get_private_key (const struct GNUNET_IDENTITY_Ego *ego)
+{
+ return ego->pk;
+}
+
+
+/**
+ * Get the identifier (public key) of an ego.
+ *
+ * @param ego identity handle with the private key
+ * @param pk set to ego's public key
+ */
+void
+GNUNET_IDENTITY_ego_get_public_key (const struct GNUNET_IDENTITY_Ego *ego,
+ struct GNUNET_CRYPTO_EcdsaPublicKey *pk)
+{
+ GNUNET_CRYPTO_ecdsa_key_get_public (ego->pk,
+ pk);
+}
+
+
+/**
+ * Obtain the identity that is currently preferred/default
+ * for a service.
+ *
+ * @param h identity service to query
+ * @param service_name for which service is an identity wanted
+ * @param cb function to call with the result (will only be called once)
+ * @param cb_cls closure for @a cb
+ * @return handle to abort the operation
+ */
+struct GNUNET_IDENTITY_Operation *
+GNUNET_IDENTITY_get (struct GNUNET_IDENTITY_Handle *h,
+ const char *service_name,
+ GNUNET_IDENTITY_Callback cb,
+ void *cb_cls)
+{
+ struct GNUNET_IDENTITY_Operation *op;
+ struct GNUNET_MQ_Envelope *env;
+ struct GetDefaultMessage *gdm;
+ size_t slen;
+
+ if (NULL == h->mq)
+ return NULL;
+ slen = strlen (service_name) + 1;
+ if (slen >= GNUNET_MAX_MESSAGE_SIZE - sizeof (struct GetDefaultMessage))
+ {
+ GNUNET_break (0);
+ return NULL;
+ }
+ op = GNUNET_new (struct GNUNET_IDENTITY_Operation);
+ op->h = h;
+ op->cb = cb;
+ op->cls = cb_cls;
+ GNUNET_CONTAINER_DLL_insert_tail (h->op_head,
+ h->op_tail,
+ op);
+ env = GNUNET_MQ_msg_extra (gdm,
+ slen,
+ GNUNET_MESSAGE_TYPE_IDENTITY_GET_DEFAULT);
+ gdm->name_len = htons (slen);
+ gdm->reserved = htons (0);
+ GNUNET_memcpy (&gdm[1],
+ service_name,
+ slen);
+ GNUNET_MQ_send (h->mq,
+ env);
+ return op;
+}
+
+
+/**
+ * Set the preferred/default identity for a service.
+ *
+ * @param h identity service to inform
+ * @param service_name for which service is an identity set
+ * @param ego new default identity to be set for this service
+ * @param cont function to call once the operation finished
+ * @param cont_cls closure for @a cont
+ * @return handle to abort the operation
+ */
+struct GNUNET_IDENTITY_Operation *
+GNUNET_IDENTITY_set (struct GNUNET_IDENTITY_Handle *h,
+ const char *service_name,
+ struct GNUNET_IDENTITY_Ego *ego,
+ GNUNET_IDENTITY_Continuation cont,
+ void *cont_cls)
+{
+ struct GNUNET_IDENTITY_Operation *op;
+ struct GNUNET_MQ_Envelope *env;
+ struct SetDefaultMessage *sdm;
+ size_t slen;
+
+ if (NULL == h->mq)
+ return NULL;
+ slen = strlen (service_name) + 1;
+ if (slen >= GNUNET_MAX_MESSAGE_SIZE - sizeof (struct SetDefaultMessage))
+ {
+ GNUNET_break (0);
+ return NULL;
+ }
+ op = GNUNET_new (struct GNUNET_IDENTITY_Operation);
+ op->h = h;
+ op->cont = cont;
+ op->cls = cont_cls;
+ GNUNET_CONTAINER_DLL_insert_tail (h->op_head,
+ h->op_tail,
+ op);
+ env = GNUNET_MQ_msg_extra (sdm,
+ slen,
+ GNUNET_MESSAGE_TYPE_IDENTITY_SET_DEFAULT);
+ sdm->name_len = htons (slen);
+ sdm->reserved = htons (0);
+ sdm->private_key = *ego->pk;
+ GNUNET_memcpy (&sdm[1],
+ service_name,
+ slen);
+ GNUNET_MQ_send (h->mq,
+ env);
+ return op;
+}
+
+
+/**
+ * Create a new identity with the given name.
+ *
+ * @param h identity service to use
+ * @param name desired name
+ * @param cont function to call with the result (will only be called once)
+ * @param cont_cls closure for @a cont
+ * @return handle to abort the operation
+ */
+struct GNUNET_IDENTITY_Operation *
+GNUNET_IDENTITY_create (struct GNUNET_IDENTITY_Handle *h,
+ const char *name,
+ GNUNET_IDENTITY_Continuation cont,
+ void *cont_cls)
+{
+ struct GNUNET_IDENTITY_Operation *op;
+ struct GNUNET_MQ_Envelope *env;
+ struct CreateRequestMessage *crm;
+ struct GNUNET_CRYPTO_EcdsaPrivateKey *pk;
+ size_t slen;
+
+ if (NULL == h->mq)
+ return NULL;
+ slen = strlen (name) + 1;
+ if (slen >= GNUNET_MAX_MESSAGE_SIZE - sizeof (struct CreateRequestMessage))
+ {
+ GNUNET_break (0);
+ return NULL;
+ }
+ op = GNUNET_new (struct GNUNET_IDENTITY_Operation);
+ op->h = h;
+ op->cont = cont;
+ op->cls = cont_cls;
+ GNUNET_CONTAINER_DLL_insert_tail (h->op_head,
+ h->op_tail,
+ op);
+ env = GNUNET_MQ_msg_extra (crm,
+ slen,
+ GNUNET_MESSAGE_TYPE_IDENTITY_CREATE);
+ crm->name_len = htons (slen);
+ crm->reserved = htons (0);
+ pk = GNUNET_CRYPTO_ecdsa_key_create ();
+ crm->private_key = *pk;
+ GNUNET_free (pk);
+ GNUNET_memcpy (&crm[1],
+ name,
+ slen);
+ GNUNET_MQ_send (h->mq,
+ env);
+ return op;
+}
+
+
+/**
+ * Renames an existing identity.
+ *
+ * @param h identity service to use
+ * @param old_name old name
+ * @param new_name desired new name
+ * @param cb function to call with the result (will only be called once)
+ * @param cb_cls closure for @a cb
+ * @return handle to abort the operation
+ */
+struct GNUNET_IDENTITY_Operation *
+GNUNET_IDENTITY_rename (struct GNUNET_IDENTITY_Handle *h,
+ const char *old_name,
+ const char *new_name,
+ GNUNET_IDENTITY_Continuation cb,
+ void *cb_cls)
+{
+ struct GNUNET_IDENTITY_Operation *op;
+ struct GNUNET_MQ_Envelope *env;
+ struct RenameMessage *grm;
+ size_t slen_old;
+ size_t slen_new;
+ char *dst;
+
+ if (NULL == h->mq)
+ return NULL;
+ slen_old = strlen (old_name) + 1;
+ slen_new = strlen (new_name) + 1;
+ if ( (slen_old >= GNUNET_MAX_MESSAGE_SIZE) ||
+ (slen_new >= GNUNET_MAX_MESSAGE_SIZE) ||
+ (slen_old + slen_new >= GNUNET_MAX_MESSAGE_SIZE - sizeof (struct RenameMessage)) )
+ {
+ GNUNET_break (0);
+ return NULL;
+ }
+ op = GNUNET_new (struct GNUNET_IDENTITY_Operation);
+ op->h = h;
+ op->cont = cb;
+ op->cls = cb_cls;
+ GNUNET_CONTAINER_DLL_insert_tail (h->op_head,
+ h->op_tail,
+ op);
+ env = GNUNET_MQ_msg_extra (grm,
+ slen_old + slen_new,
+ GNUNET_MESSAGE_TYPE_IDENTITY_RENAME);
+ grm->old_name_len = htons (slen_old);
+ grm->new_name_len = htons (slen_new);
+ dst = (char *) &grm[1];
+ GNUNET_memcpy (dst,
+ old_name,
+ slen_old);
+ GNUNET_memcpy (&dst[slen_old],
+ new_name,
+ slen_new);
+ GNUNET_MQ_send (h->mq,
+ env);
+ return op;
+}
+
+
+/**
+ * Delete an existing identity.
+ *
+ * @param h identity service to use
+ * @param name name of the identity to delete
+ * @param cb function to call with the result (will only be called once)
+ * @param cb_cls closure for @a cb
+ * @return handle to abort the operation
+ */
+struct GNUNET_IDENTITY_Operation *
+GNUNET_IDENTITY_delete (struct GNUNET_IDENTITY_Handle *h,
+ const char *name,
+ GNUNET_IDENTITY_Continuation cb,
+ void *cb_cls)
+{
+ struct GNUNET_IDENTITY_Operation *op;
+ struct GNUNET_MQ_Envelope *env;
+ struct DeleteMessage *gdm;
+ size_t slen;
+
+ if (NULL == h->mq)
+ return NULL;
+ slen = strlen (name) + 1;
+ if (slen >= GNUNET_MAX_MESSAGE_SIZE - sizeof (struct DeleteMessage))
+ {
+ GNUNET_break (0);
+ return NULL;
+ }
+ op = GNUNET_new (struct GNUNET_IDENTITY_Operation);
+ op->h = h;
+ op->cont = cb;
+ op->cls = cb_cls;
+ GNUNET_CONTAINER_DLL_insert_tail (h->op_head,
+ h->op_tail,
+ op);
+ env = GNUNET_MQ_msg_extra (gdm,
+ slen,
+ GNUNET_MESSAGE_TYPE_IDENTITY_DELETE);
+ gdm->name_len = htons (slen);
+ gdm->reserved = htons (0);
+ GNUNET_memcpy (&gdm[1],
+ name,
+ slen);
+ GNUNET_MQ_send (h->mq,
+ env);
+ return op;
+}
+
+
+/**
+ * Cancel an identity operation. Note that the operation MAY still
+ * be executed; this merely cancels the continuation; if the request
+ * was already transmitted, the service may still choose to complete
+ * the operation.
+ *
+ * @param op operation to cancel
+ */
+void
+GNUNET_IDENTITY_cancel (struct GNUNET_IDENTITY_Operation *op)
+{
+ op->cont = NULL;
+ op->cb = NULL;