/* Generate a private DSA key for a given account, storing it into a * FILE*, and loading it into the given OtrlUserState. Overwrite any * previously generated keys for that account in that OtrlUserState. * The FILE* must be open for reading and writing. */ gcry_error_t otrl_privkey_generate_FILEp(OtrlUserState us, FILE *privf, const char *accountname, const char *protocol) { gcry_error_t err; gcry_sexp_t key, parms, privkey; static const char *parmstr = "(genkey (dsa (nbits 4:1024)))"; OtrlPrivKey *p; if (!privf) return gcry_error(GPG_ERR_NO_ERROR); /* Create a DSA key */ err = gcry_sexp_new(&parms, parmstr, strlen(parmstr), 0); if (err) { return err; } err = gcry_pk_genkey(&key, parms); gcry_sexp_release(parms); if (err) { return err; } /* Extract the privkey */ privkey = gcry_sexp_find_token(key, "private-key", 0); gcry_sexp_release(key); /* Output the other keys we know */ fprintf(privf, "(privkeys\n"); for (p=us->privkey_root; p; p=p->next) { /* Skip this one if our new key replaces it */ if (!strcmp(p->accountname, accountname) && !strcmp(p->protocol, protocol)) { continue; } account_write(privf, p->accountname, p->protocol, p->privkey); } account_write(privf, accountname, protocol, privkey); gcry_sexp_release(privkey); fprintf(privf, ")\n"); fseek(privf, 0, SEEK_SET); return otrl_privkey_read_FILEp(us, privf); }
/* Read a sets of private DSA keys from a file on disk into the given * OtrlUserState. */ gcry_error_t otrl_privkey_read(OtrlUserState us, const char *filename) { FILE *privf; gcry_error_t err; /* Open the privkey file. We use rb mode so that on WIN32, fread() * reads the same number of bytes that fstat() indicates are in the * file. */ privf = fopen(filename, "rb"); if (!privf) { err = gcry_error_from_errno(errno); return err; } err = otrl_privkey_read_FILEp(us, privf); fclose(privf); return err; }
static void* read_keys_background(void* data) { VALUE* argv = data; VALUE self = argv[0], file = argv[1]; gcry_error_t err; OtrlUserState us; int fd; FILE* fp; Data_Get_Struct(self, struct s_OtrlUserState, us); if (rb_obj_is_instance_of(file, rb_cFile)) { fd = FIX2INT(rb_funcall(file, rb_intern("fileno"), 0)); fp = fdopen(dup(fd), "rb"); err = otrl_privkey_read_FILEp(us, fp); fclose(fp); } else if (rb_obj_is_instance_of(file, rb_cString)) { err = otrl_privkey_read(us, RSTRING_PTR(file)); } return err; }