⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 ssh-keygen.c

📁 OpenSSL Source code for SFTP, SSH, and many others
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * Author: Tatu Ylonen <ylo@cs.hut.fi> * Copyright (c) 1994 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland *                    All rights reserved * Identity and host key generation and maintenance. * * As far as I am concerned, the code I have written for this software * can be used freely for any purpose.  Any derived versions of this * software must be clearly marked as such, and if the derived work is * incompatible with the protocol description in the RFC file, it must be * called by a name other than "ssh" or "Secure Shell". */#include "includes.h"RCSID("$OpenBSD: ssh-keygen.c,v 1.100 2002/06/19 00:27:55 deraadt Exp $");#include <openssl/evp.h>#include <openssl/pem.h>#include "xmalloc.h"#include "key.h"#include "rsa.h"#include "authfile.h"#include "uuencode.h"#include "buffer.h"#include "bufaux.h"#include "pathnames.h"#include "log.h"#include "readpass.h"#ifdef SMARTCARD#include "scard.h"#endif/* Number of bits in the RSA/DSA key.  This value can be changed on the command line. */int bits = 1024;/* * Flag indicating that we just want to change the passphrase.  This can be * set on the command line. */int change_passphrase = 0;/* * Flag indicating that we just want to change the comment.  This can be set * on the command line. */int change_comment = 0;int quiet = 0;/* Flag indicating that we just want to see the key fingerprint */int print_fingerprint = 0;int print_bubblebabble = 0;/* The identity file name, given on the command line or entered by the user. */char identity_file[1024];int have_identity = 0;/* This is set to the passphrase if given on the command line. */char *identity_passphrase = NULL;/* This is set to the new passphrase if given on the command line. */char *identity_new_passphrase = NULL;/* This is set to the new comment if given on the command line. */char *identity_comment = NULL;/* Dump public key file in format used by real and the original SSH 2 */int convert_to_ssh2 = 0;int convert_from_ssh2 = 0;int print_public = 0;char *key_type_name = NULL;/* argv0 */#ifdef HAVE___PROGNAMEextern char *__progname;#elsechar *__progname;#endifchar hostname[MAXHOSTNAMELEN];static voidask_filename(struct passwd *pw, const char *prompt){	char buf[1024];	char *name = NULL;	if (key_type_name == NULL)		name = _PATH_SSH_CLIENT_ID_RSA;	else		switch (key_type_from_name(key_type_name)) {		case KEY_RSA1:			name = _PATH_SSH_CLIENT_IDENTITY;			break;		case KEY_DSA:			name = _PATH_SSH_CLIENT_ID_DSA;			break;		case KEY_RSA:			name = _PATH_SSH_CLIENT_ID_RSA;			break;		default:			fprintf(stderr, "bad key type");			exit(1);			break;		}	snprintf(identity_file, sizeof(identity_file), "%s/%s", pw->pw_dir, name);	fprintf(stderr, "%s (%s): ", prompt, identity_file);	fflush(stderr);	if (fgets(buf, sizeof(buf), stdin) == NULL)		exit(1);	if (strchr(buf, '\n'))		*strchr(buf, '\n') = 0;	if (strcmp(buf, "") != 0)		strlcpy(identity_file, buf, sizeof(identity_file));	have_identity = 1;}static Key *load_identity(char *filename){	char *pass;	Key *prv;	prv = key_load_private(filename, "", NULL);	if (prv == NULL) {		if (identity_passphrase)			pass = xstrdup(identity_passphrase);		else			pass = read_passphrase("Enter passphrase: ",			    RP_ALLOW_STDIN);		prv = key_load_private(filename, pass, NULL);		memset(pass, 0, strlen(pass));		xfree(pass);	}	return prv;}#define SSH_COM_PUBLIC_BEGIN		"---- BEGIN SSH2 PUBLIC KEY ----"#define SSH_COM_PUBLIC_END		"---- END SSH2 PUBLIC KEY ----"#define SSH_COM_PRIVATE_BEGIN		"---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----"#define	SSH_COM_PRIVATE_KEY_MAGIC	0x3f6ff9ebstatic voiddo_convert_to_ssh2(struct passwd *pw){	Key *k;	u_int len;	u_char *blob;	struct stat st;	if (!have_identity)		ask_filename(pw, "Enter file in which the key is");	if (stat(identity_file, &st) < 0) {		perror(identity_file);		exit(1);	}	if ((k = key_load_public(identity_file, NULL)) == NULL) {		if ((k = load_identity(identity_file)) == NULL) {			fprintf(stderr, "load failed\n");			exit(1);		}	}	if (key_to_blob(k, &blob, &len) <= 0) {		fprintf(stderr, "key_to_blob failed\n");		exit(1);	}	fprintf(stdout, "%s\n", SSH_COM_PUBLIC_BEGIN);	fprintf(stdout,	    "Comment: \"%d-bit %s, converted from OpenSSH by %s@%s\"\n",	    key_size(k), key_type(k),	    pw->pw_name, hostname);	dump_base64(stdout, blob, len);	fprintf(stdout, "%s\n", SSH_COM_PUBLIC_END);	key_free(k);	xfree(blob);	exit(0);}static voidbuffer_get_bignum_bits(Buffer *b, BIGNUM *value){	int bits = buffer_get_int(b);	int bytes = (bits + 7) / 8;	if (buffer_len(b) < bytes)		fatal("buffer_get_bignum_bits: input buffer too small: "		    "need %d have %d", bytes, buffer_len(b));	BN_bin2bn(buffer_ptr(b), bytes, value);	buffer_consume(b, bytes);}static Key *do_convert_private_ssh2_from_blob(u_char *blob, u_int blen){	Buffer b;	Key *key = NULL;	char *type, *cipher;	u_char *sig, data[] = "abcde12345";	int magic, rlen, ktype, i1, i2, i3, i4;	u_int slen;	u_long e;	buffer_init(&b);	buffer_append(&b, blob, blen);	magic  = buffer_get_int(&b);	if (magic != SSH_COM_PRIVATE_KEY_MAGIC) {		error("bad magic 0x%x != 0x%x", magic, SSH_COM_PRIVATE_KEY_MAGIC);		buffer_free(&b);		return NULL;	}	i1 = buffer_get_int(&b);	type   = buffer_get_string(&b, NULL);	cipher = buffer_get_string(&b, NULL);	i2 = buffer_get_int(&b);	i3 = buffer_get_int(&b);	i4 = buffer_get_int(&b);	debug("ignore (%d %d %d %d)", i1,i2,i3,i4);	if (strcmp(cipher, "none") != 0) {		error("unsupported cipher %s", cipher);		xfree(cipher);		buffer_free(&b);		xfree(type);		return NULL;	}	xfree(cipher);	if (strstr(type, "dsa")) {		ktype = KEY_DSA;	} else if (strstr(type, "rsa")) {		ktype = KEY_RSA;	} else {		xfree(type);		return NULL;	}	key = key_new_private(ktype);	xfree(type);	switch (key->type) {	case KEY_DSA:		buffer_get_bignum_bits(&b, key->dsa->p);		buffer_get_bignum_bits(&b, key->dsa->g);		buffer_get_bignum_bits(&b, key->dsa->q);		buffer_get_bignum_bits(&b, key->dsa->pub_key);		buffer_get_bignum_bits(&b, key->dsa->priv_key);		break;	case KEY_RSA:		e  = buffer_get_char(&b);		debug("e %lx", e);		if (e < 30) {			e <<= 8;			e += buffer_get_char(&b);			debug("e %lx", e);			e <<= 8;			e += buffer_get_char(&b);			debug("e %lx", e);		}		if (!BN_set_word(key->rsa->e, e)) {			buffer_free(&b);			key_free(key);			return NULL;		}		buffer_get_bignum_bits(&b, key->rsa->d);		buffer_get_bignum_bits(&b, key->rsa->n);		buffer_get_bignum_bits(&b, key->rsa->iqmp);		buffer_get_bignum_bits(&b, key->rsa->q);		buffer_get_bignum_bits(&b, key->rsa->p);		rsa_generate_additional_parameters(key->rsa);		break;	}	rlen = buffer_len(&b);	if (rlen != 0)		error("do_convert_private_ssh2_from_blob: "		    "remaining bytes in key blob %d", rlen);	buffer_free(&b);	/* try the key */	key_sign(key, &sig, &slen, data, sizeof(data));	key_verify(key, sig, slen, data, sizeof(data));	xfree(sig);	return key;}static voiddo_convert_from_ssh2(struct passwd *pw){	Key *k;	int blen;	u_int len;	char line[1024], *p;	u_char blob[8096];	char encoded[8096];	struct stat st;	int escaped = 0, private = 0, ok;	FILE *fp;	if (!have_identity)		ask_filename(pw, "Enter file in which the key is");	if (stat(identity_file, &st) < 0) {		perror(identity_file);		exit(1);	}	fp = fopen(identity_file, "r");	if (fp == NULL) {		perror(identity_file);		exit(1);	}	encoded[0] = '\0';	while (fgets(line, sizeof(line), fp)) {		if (!(p = strchr(line, '\n'))) {			fprintf(stderr, "input line too long.\n");			exit(1);		}		if (p > line && p[-1] == '\\')			escaped++;		if (strncmp(line, "----", 4) == 0 ||		    strstr(line, ": ") != NULL) {			if (strstr(line, SSH_COM_PRIVATE_BEGIN) != NULL)				private = 1;			if (strstr(line, " END ") != NULL) {				break;			}			/* fprintf(stderr, "ignore: %s", line); */			continue;		}		if (escaped) {			escaped--;			/* fprintf(stderr, "escaped: %s", line); */			continue;		}		*p = '\0';		strlcat(encoded, line, sizeof(encoded));	}	len = strlen(encoded);	if (((len % 4) == 3) &&	    (encoded[len-1] == '=') &&	    (encoded[len-2] == '=') &&	    (encoded[len-3] == '='))		encoded[len-3] = '\0';	blen = uudecode(encoded, blob, sizeof(blob));	if (blen < 0) {		fprintf(stderr, "uudecode failed.\n");		exit(1);	}	k = private ?	    do_convert_private_ssh2_from_blob(blob, blen) :	    key_from_blob(blob, blen);	if (k == NULL) {		fprintf(stderr, "decode blob failed.\n");		exit(1);	}	ok = private ?	    (k->type == KEY_DSA ?		 PEM_write_DSAPrivateKey(stdout, k->dsa, NULL, NULL, 0, NULL, NULL) :		 PEM_write_RSAPrivateKey(stdout, k->rsa, NULL, NULL, 0, NULL, NULL)) :	    key_write(k, stdout);	if (!ok) {		fprintf(stderr, "key write failed");		exit(1);	}	key_free(k);	if (!private)		fprintf(stdout, "\n");	fclose(fp);	exit(0);}static voiddo_print_public(struct passwd *pw){	Key *prv;	struct stat st;	if (!have_identity)		ask_filename(pw, "Enter file in which the key is");	if (stat(identity_file, &st) < 0) {		perror(identity_file);		exit(1);	}	prv = load_identity(identity_file);	if (prv == NULL) {		fprintf(stderr, "load failed\n");		exit(1);	}	if (!key_write(prv, stdout))		fprintf(stderr, "key_write failed");	key_free(prv);	fprintf(stdout, "\n");	exit(0);}#ifdef SMARTCARDstatic voiddo_upload(struct passwd *pw, const char *sc_reader_id){	Key *prv = NULL;	struct stat st;	int ret;	if (!have_identity)		ask_filename(pw, "Enter file in which the key is");	if (stat(identity_file, &st) < 0) {		perror(identity_file);		exit(1);	}	prv = load_identity(identity_file);	if (prv == NULL) {		error("load failed");		exit(1);	}	ret = sc_put_key(prv, sc_reader_id);	key_free(prv);	if (ret < 0)		exit(1);	log("loading key done");	exit(0);}static voiddo_download(struct passwd *pw, const char *sc_reader_id){	Key **keys = NULL;	int i;	keys = sc_get_keys(sc_reader_id, NULL);	if (keys == NULL)		fatal("cannot read public key from smartcard");	for (i = 0; keys[i]; i++) {		key_write(keys[i], stdout);		key_free(keys[i]);		fprintf(stdout, "\n");	}	xfree(keys);	exit(0);}#endif /* SMARTCARD */static voiddo_fingerprint(struct passwd *pw){	FILE *f;	Key *public;	char *comment = NULL, *cp, *ep, line[16*1024], *fp;	int i, skip = 0, num = 1, invalid = 1;	enum fp_rep rep;	enum fp_type fptype;	struct stat st;	fptype = print_bubblebabble ? SSH_FP_SHA1 : SSH_FP_MD5;	rep =    print_bubblebabble ? SSH_FP_BUBBLEBABBLE : SSH_FP_HEX;	if (!have_identity)		ask_filename(pw, "Enter file in which the key is");	if (stat(identity_file, &st) < 0) {		perror(identity_file);		exit(1);	}	public = key_load_public(identity_file, &comment);	if (public != NULL) {		fp = key_fingerprint(public, fptype, rep);		printf("%d %s %s\n", key_size(public), fp, comment);		key_free(public);		xfree(comment);		xfree(fp);		exit(0);	}	if (comment)		xfree(comment);	f = fopen(identity_file, "r");	if (f != NULL) {		while (fgets(line, sizeof(line), f)) {			i = strlen(line) - 1;			if (line[i] != '\n') {				error("line %d too long: %.40s...", num, line);				skip = 1;				continue;			}			num++;			if (skip) {				skip = 0;				continue;			}			line[i] = '\0';			/* Skip leading whitespace, empty and comment lines. */			for (cp = line; *cp == ' ' || *cp == '\t'; cp++)				;			if (!*cp || *cp == '\n' || *cp == '#')				continue ;			i = strtol(cp, &ep, 10);			if (i == 0 || ep == NULL || (*ep != ' ' && *ep != '\t')) {				int quoted = 0;				comment = cp;				for (; *cp && (quoted || (*cp != ' ' && *cp != '\t')); cp++) {					if (*cp == '\\' && cp[1] == '"')						cp++;	/* Skip both */					else if (*cp == '"')

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -