int openssl_read_pem_seckey(const char *f, __ops_key_t *key, const char *type, int verbose) { FILE *fp; DSA *dsa; RSA *rsa; int ok; OpenSSL_add_all_algorithms(); if ((fp = fopen(f, "r")) == NULL) { if (verbose) { (void) fprintf(stderr, "can't open '%s'\n", f); } return 0; } ok = 1; if (strcmp(type, "ssh-rsa") == 0) { rsa = PEM_read_RSAPrivateKey(fp, NULL, NULL, NULL); key->key.seckey.key.rsa.d = rsa->d; key->key.seckey.key.rsa.p = rsa->p; key->key.seckey.key.rsa.q = rsa->q; key->key.seckey.key.rsa.d = rsa->d; } else if (strcmp(type, "ssh-dss") == 0) { if ((dsa = PEM_read_DSAPrivateKey(fp, NULL, NULL, NULL)) == NULL) { ok = 0; } else { key->key.seckey.key.dsa.x = dsa->priv_key; } } else { ok = 0; } (void) fclose(fp); return ok; }
/* See up there, the '(c) == 0' part? The read functions return NULL and the write functions return (int)0 for failure. So, checking for zero up there is fine, but don't go using this for general purpose stuff. */ static int load_keys(const char *pubfn, const char *privfn, DSA **dsa) { FILE *f; LK_act_key(pubfn, PEM_read_DSA_PUBKEY(f, dsa, NULL, NULL), "r", "Could not open %s for reading!\n", "Could not read a DSA public key from %s!\n"); LK_act_key(privfn, PEM_read_DSAPrivateKey(f, dsa, NULL, NULL), "r", "Could not open %s for reading!\n", "Could not read a DSA private key from %s!\n"); return 0; }
int openssl_read_pem_seckey(const char *f, __ops_key_t *key, const char *type, int verbose) { FILE *fp; char prompt[BUFSIZ]; char *pass; DSA *dsa; RSA *rsa; int ok; OpenSSL_add_all_algorithms(); if ((fp = fopen(f, "r")) == NULL) { if (verbose) { (void) fprintf(stderr, "can't open '%s'\n", f); } return 0; } ok = 1; if (strcmp(type, "ssh-rsa") == 0) { if ((rsa = PEM_read_RSAPrivateKey(fp, NULL, NULL, NULL)) == NULL) { (void) snprintf(prompt, sizeof(prompt), "netpgp PEM %s passphrase: ", f); do { pass = getpass(prompt); rsa = PEM_read_RSAPrivateKey(fp, NULL, NULL, pass); } while (rsa == NULL); } key->key.seckey.key.rsa.d = rsa->d; key->key.seckey.key.rsa.p = rsa->p; key->key.seckey.key.rsa.q = rsa->q; key->key.seckey.key.rsa.d = rsa->d; } else if (strcmp(type, "ssh-dss") == 0) { if ((dsa = PEM_read_DSAPrivateKey(fp, NULL, NULL, NULL)) == NULL) { ok = 0; } else { key->key.seckey.key.dsa.x = dsa->priv_key; } } else { ok = 0; } (void) fclose(fp); return ok; }
/** \brief Reads a SSH private key from a file * \param session SSH Session * \param filename Filename containing the private key * \param type Type of the private key. One of TYPE_DSS or TYPE_RSA. Pass 0 to automatically detect the type. * \param passphrase Passphrase to decrypt the private key. Set to null if none is needed or it is unknown. * \returns a PRIVATE_KEY object containing the private key, or NULL if it failed. * \see privatekey_free() * \see publickey_from_privatekey() */ ssh_private_key privatekey_from_file(ssh_session session, const char *filename, int type, const char *passphrase) { ssh_auth_callback auth_cb = NULL; ssh_private_key privkey = NULL; void *auth_ud = NULL; FILE *file = NULL; #ifdef HAVE_LIBGCRYPT gcry_sexp_t dsa = NULL; gcry_sexp_t rsa = NULL; int valid; #elif defined HAVE_LIBCRYPTO DSA *dsa = NULL; RSA *rsa = NULL; #endif ssh_log(session, SSH_LOG_RARE, "Trying to open %s", filename); file = fopen(filename,"r"); if (file == NULL) { ssh_set_error(session, SSH_REQUEST_DENIED, "Error opening %s: %s", filename, strerror(errno)); return NULL; } ssh_log(session, SSH_LOG_RARE, "Trying to read %s, passphase=%s, authcb=%s", filename, passphrase ? "true" : "false", session->callbacks && session->callbacks->auth_function ? "true" : "false"); if (type == 0) { type = privatekey_type_from_file(file); if (type == 0) { fclose(file); ssh_set_error(session, SSH_FATAL, "Invalid private key file."); return NULL; } } switch (type) { case TYPE_DSS: if (passphrase == NULL) { if (session->callbacks && session->callbacks->auth_function) { auth_cb = session->callbacks->auth_function; auth_ud = session->callbacks->userdata; #ifdef HAVE_LIBGCRYPT valid = read_dsa_privatekey(file, &dsa, auth_cb, auth_ud, "Passphrase for private key:"); } else { /* authcb */ valid = read_dsa_privatekey(file, &dsa, NULL, NULL, NULL); } /* authcb */ } else { /* passphrase */ valid = read_dsa_privatekey(file, &dsa, NULL, (void *) passphrase, NULL); } fclose(file); if (!valid) { ssh_set_error(session, SSH_FATAL, "Parsing private key %s", filename); #elif defined HAVE_LIBCRYPTO dsa = PEM_read_DSAPrivateKey(file, NULL, pem_get_password, session); } else { /* authcb */ /* openssl uses it's own callback to get the passphrase here */ dsa = PEM_read_DSAPrivateKey(file, NULL, NULL, NULL); } /* authcb */ } else { /* passphrase */
valid = read_dsa_privatekey(file, &dsa, NULL, (void *) passphrase, NULL); } fclose(file); if (!valid) { ssh_set_error(session, SSH_FATAL, "Parsing private key %s", filename); #elif defined HAVE_LIBCRYPTO dsa = PEM_read_DSAPrivateKey(file, NULL, pem_get_password, session); } else { /* authcb */ /* openssl uses it's own callback to get the passphrase here */ dsa = PEM_read_DSAPrivateKey(file, NULL, NULL, NULL); } /* authcb */ } else { /* passphrase */ dsa = PEM_read_DSAPrivateKey(file, NULL, NULL, (void *) passphrase); } fclose(file); if (dsa == NULL) { ssh_set_error(session, SSH_FATAL, "Parsing private key %s: %s", filename, ERR_error_string(ERR_get_error(), NULL)); #endif return NULL; } break; case TYPE_RSA: if (passphrase == NULL) { if (session->callbacks && session->callbacks->auth_function) { auth_cb = session->callbacks->auth_function;
inline dsa_key dsa_key::from_private_key(file _file, pem_passphrase_callback_type callback, void* callback_arg) { return take_ownership(PEM_read_DSAPrivateKey(_file.raw(), NULL, callback, callback_arg)); }