/* Create a public key pair and return it in r_key. How the key is created depends on s_parms: (genkey (algo (parameter_name_1 ....) .... (parameter_name_n ....) )) The key is returned in a format depending on the algorithm. Both, private and secret keys are returned and optionally some additional informatin. For elgamal we return this structure: (key-data (public-key (elg (p <mpi>) (g <mpi>) (y <mpi>) ) ) (private-key (elg (p <mpi>) (g <mpi>) (y <mpi>) (x <mpi>) ) ) (misc-key-info (pm1-factors n1 n2 ... nn) )) */ gcry_err_code_t _gcry_pk_genkey (gcry_sexp_t *r_key, gcry_sexp_t s_parms) { gcry_pk_spec_t *spec = NULL; gcry_sexp_t list = NULL; gcry_sexp_t l2 = NULL; char *name = NULL; gcry_err_code_t rc; *r_key = NULL; list = sexp_find_token (s_parms, "genkey", 0); if (!list) { rc = GPG_ERR_INV_OBJ; /* Does not contain genkey data. */ goto leave; } l2 = sexp_cadr (list); sexp_release (list); list = l2; l2 = NULL; if (! list) { rc = GPG_ERR_NO_OBJ; /* No cdr for the genkey. */ goto leave; } name = _gcry_sexp_nth_string (list, 0); if (!name) { rc = GPG_ERR_INV_OBJ; /* Algo string missing. */ goto leave; } spec = spec_from_name (name); xfree (name); name = NULL; if (!spec) { rc = GPG_ERR_PUBKEY_ALGO; /* Unknown algorithm. */ goto leave; } if (spec->generate) rc = spec->generate (list, r_key); else rc = GPG_ERR_NOT_IMPLEMENTED; leave: sexp_release (list); xfree (name); sexp_release (l2); return rc; }
/* Given the s-expression SEXP with the first element be either * "private-key" or "public-key" return the spec structure for it. We * look through the list to find a list beginning with "private-key" * or "public-key" - the first one found is used. If WANT_PRIVATE is * set the function will only succeed if a private key has been given. * On success the spec is stored at R_SPEC. On error NULL is stored * at R_SPEC and an error code returned. If R_PARMS is not NULL and * the fucntion returns success, the parameter list below * "private-key" or "public-key" is stored there and the caller must * call gcry_sexp_release on it. */ static gcry_err_code_t spec_from_sexp (gcry_sexp_t sexp, int want_private, gcry_pk_spec_t **r_spec, gcry_sexp_t *r_parms) { gcry_sexp_t list, l2; char *name; gcry_pk_spec_t *spec; *r_spec = NULL; if (r_parms) *r_parms = NULL; /* Check that the first element is valid. If we are looking for a public key but a private key was supplied, we allow the use of the private key anyway. The rationale for this is that the private key is a superset of the public key. */ list = sexp_find_token (sexp, want_private? "private-key":"public-key", 0); if (!list && !want_private) list = sexp_find_token (sexp, "private-key", 0); if (!list) return GPG_ERR_INV_OBJ; /* Does not contain a key object. */ l2 = sexp_cadr (list); sexp_release (list); list = l2; name = sexp_nth_string (list, 0); if (!name) { sexp_release ( list ); return GPG_ERR_INV_OBJ; /* Invalid structure of object. */ } spec = spec_from_name (name); xfree (name); if (!spec) { sexp_release (list); return GPG_ERR_PUBKEY_ALGO; /* Unknown algorithm. */ } *r_spec = spec; if (r_parms) *r_parms = list; else sexp_release (list); return 0; }
/* Return the so called KEYGRIP which is the SHA-1 hash of the public key parameters expressed in a way depending on the algorithm. ARRAY must either be 20 bytes long or NULL; in the latter case a newly allocated array of that size is returned, otherwise ARRAY or NULL is returned to indicate an error which is most likely an unknown algorithm. The function accepts public or secret keys. */ unsigned char * _gcry_pk_get_keygrip (gcry_sexp_t key, unsigned char *array) { gcry_sexp_t list = NULL; gcry_sexp_t l2 = NULL; gcry_pk_spec_t *spec = NULL; const char *s; char *name = NULL; int idx; const char *elems; gcry_md_hd_t md = NULL; int okay = 0; /* Check that the first element is valid. */ list = sexp_find_token (key, "public-key", 0); if (! list) list = sexp_find_token (key, "private-key", 0); if (! list) list = sexp_find_token (key, "protected-private-key", 0); if (! list) list = sexp_find_token (key, "shadowed-private-key", 0); if (! list) return NULL; /* No public- or private-key object. */ l2 = sexp_cadr (list); sexp_release (list); list = l2; l2 = NULL; name = _gcry_sexp_nth_string (list, 0); if (!name) goto fail; /* Invalid structure of object. */ spec = spec_from_name (name); if (!spec) goto fail; /* Unknown algorithm. */ elems = spec->elements_grip; if (!elems) goto fail; /* No grip parameter. */ if (_gcry_md_open (&md, GCRY_MD_SHA1, 0)) goto fail; if (spec->comp_keygrip) { /* Module specific method to compute a keygrip. */ if (spec->comp_keygrip (md, list)) goto fail; } else { /* Generic method to compute a keygrip. */ for (idx = 0, s = elems; *s; s++, idx++) { const char *data; size_t datalen; char buf[30]; l2 = sexp_find_token (list, s, 1); if (! l2) goto fail; data = sexp_nth_data (l2, 1, &datalen); if (! data) goto fail; _snprintf (buf, sizeof buf, "(1:%c%u:", *s, (unsigned int)datalen); _gcry_md_write (md, buf, strlen (buf)); _gcry_md_write (md, data, datalen); sexp_release (l2); l2 = NULL; _gcry_md_write (md, ")", 1); } } if (!array) { array = xtrymalloc (20); if (! array) goto fail; } memcpy (array, _gcry_md_read (md, GCRY_MD_SHA1), 20); okay = 1; fail: xfree (name); sexp_release (l2); _gcry_md_close (md); sexp_release (list); return okay? array : NULL; }
void sexp_build_srv (sexp ctx, sexp_plan9_srv s, sexp ls) { s->context = ctx; s->auth = s->attach = s->walk = s->walk1 = s->clone = s->open = s->create = s->remove = s->read = s->write = s->stat = s->wstat = s->flush = s->destroyfid = s->destroyreq = s->end = SEXP_FALSE; for ( ; sexp_pairp(ls) && sexp_pairp(sexp_cdr(ls)); ls=sexp_cddr(ls)) { if (sexp_car(ls) == sexp_intern(ctx, "auth:", -1)) { s->auth = sexp_cadr(ls); } else if (sexp_car(ls) == sexp_intern(ctx, "attach:", -1)) { s->attach = sexp_cadr(ls); } else if (sexp_car(ls) == sexp_intern(ctx, "walk:", -1)) { s->walk = sexp_cadr(ls); } else if (sexp_car(ls) == sexp_intern(ctx, "walk1:", -1)) { s->walk1 = sexp_cadr(ls); } else if (sexp_car(ls) == sexp_intern(ctx, "clone:", -1)) { s->clone = sexp_cadr(ls); } else if (sexp_car(ls) == sexp_intern(ctx, "open:", -1)) { s->open = sexp_cadr(ls); } else if (sexp_car(ls) == sexp_intern(ctx, "create:", -1)) { s->create = sexp_cadr(ls); } else if (sexp_car(ls) == sexp_intern(ctx, "remove:", -1)) { s->remove = sexp_cadr(ls); } else if (sexp_car(ls) == sexp_intern(ctx, "read:", -1)) { s->read = sexp_cadr(ls); } else if (sexp_car(ls) == sexp_intern(ctx, "write:", -1)) { s->write = sexp_cadr(ls); } else if (sexp_car(ls) == sexp_intern(ctx, "stat:", -1)) { s->stat = sexp_cadr(ls); } else if (sexp_car(ls) == sexp_intern(ctx, "wstat:", -1)) { s->wstat = sexp_cadr(ls); } else if (sexp_car(ls) == sexp_intern(ctx, "flush:", -1)) { s->flush = sexp_cadr(ls); } else if (sexp_car(ls) == sexp_intern(ctx, "destroyfid:", -1)) { s->destroyfid = sexp_cadr(ls); } else if (sexp_car(ls) == sexp_intern(ctx, "destroyreq:", -1)) { s->destroyreq = sexp_cadr(ls); } else if (sexp_car(ls) == sexp_intern(ctx, "end:", -1)) { s->end = sexp_cadr(ls); } } }