#include #include #include #include #include #include #include extern const char *__progname; #include "b64.h" #include "util.h" #include "cmdline.h" #include "keyfiles.h" #include "interact.h" #include "stdio-util.h" #include "priv-crypto.h" #include "keygen.h" static void add_dir(const char **vp) { if (!index(*vp,'/')) { const char *d; char *t; d = get_sshdir("key-file directory"); asprintf(&t,"%s/%s",d,*vp); *vp = t; } } void gen_key(void) { HKALG *a; int i; int j; char *pubdata; int publen; FILE *pubf; char *privdata; int privlen; FILE *privf; int size; if (keysize) { long int li; char *end; li = strtol(keysize,&end,0); if ((end == keysize) || *end) { fprintf(stderr,"%s: invalid -keysize %s\n",__progname,keysize); exit(1); } size = li; if ((size < 0) || (size != li)) { fprintf(stderr,"%s: -keysize %s: out of range\n",__progname,keysize); exit(1); } } else { size = 0; } do <"found"> { for (i=0;(a=hkalg_enum(i));i++) if (!strcmp(keytype,a->name)) break <"found">; for (i=0;(a=hkalg_enum(i));i++) for (j=0;a->altnames[j];j++) if (!strcmp(keytype,a->altnames[j])) break <"found">; fprintf(stderr,"%s: unknown key type `%s'\n",__progname,keytype); fprintf(stderr,"Known types:\n"); for (i=0;(a=hkalg_enum(i));i++) { const char *pre; const char *post; fprintf(stderr,"\t%s",a->name); pre = " (aka "; post = ""; for (j=0;a->altnames[j];j++) { fprintf(stderr,"%s%s",pre,a->altnames[j]); pre = ", "; post = ")"; } fprintf(stderr,"%s\n",post); } exit(1); } while (0); if (!keyfile_pub || !keyfile_priv) { if (! keyfile) keyfile = a->deffile; if (! keyfile_pub) keyfile_pub = keyfile; if (! keyfile_priv) keyfile_priv = keyfile; } add_dir(&keyfile_pub); add_dir(&keyfile_priv); printf("Generating %s key\n",a->name); if (!strcmp(keyfile_pub,keyfile_priv)) { printf("Output file: %s\n",keyfile_pub); } else { printf("Public portion: %s\n",keyfile_pub); printf("Private portion: %s\n",keyfile_priv); } pubf = fopen_alloc(&pubdata,&publen); privf = fopen_alloc(&privdata,&privlen); (*a->genkey)(pubf,privf,size); fclose(pubf); fclose(privf); if (! comment) { char *user; int n; char *buf; char *t; user = getenv("USER"); n = 8; while (1) { buf = malloc(n); buf[n-1] = '\0'; gethostname(buf,n); if (buf[n-1] == '\0') break; free(buf); n *= 2; } asprintf(&t,"%s@%s",user?:"(unknown)",buf); free(buf); comment = t; } { void *t; int l; priv_wrap(privdata,privlen,&t,&l,passphrase); bzero(privdata,privlen); free(privdata); privdata = t; privlen = l; } write_key(keyfile_pub,a,pubdata,publen,comment,keyfile_priv,privdata,privlen); printf("Done.\n"); } void set_comment(void) { void *pub; int publen; HKALG *alg; FILE *errf; char *comm; int atnl; static int w(void *cookie __attribute__((__unused__)), const char *buf, int len) { int i; for (i=0;i