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

📄 import.c

📁 大名鼎鼎的远程登录软件putty的Symbian版源码
💻 C
📖 第 1 页 / 共 4 页
字号:
/* * Code for PuTTY to import and export private key files in other * SSH clients' formats. */#include <stdio.h>#include <stdlib.h>#include <assert.h>#include <ctype.h>#include "putty.h"#include "ssh.h"#include "misc.h"#define PUT_32BIT(cp, value) do { \  (cp)[3] = (unsigned char)(value); \  (cp)[2] = (unsigned char)((value) >> 8); \  (cp)[1] = (unsigned char)((value) >> 16); \  (cp)[0] = (unsigned char)((value) >> 24); } while (0)#define GET_32BIT(cp) \    (((unsigned long)(unsigned char)(cp)[0] << 24) | \    ((unsigned long)(unsigned char)(cp)[1] << 16) | \    ((unsigned long)(unsigned char)(cp)[2] << 8) | \    ((unsigned long)(unsigned char)(cp)[3]))int openssh_encrypted(const Filename *filename);struct ssh2_userkey *openssh_read(const Filename *filename, char *passphrase);int openssh_write(const Filename *filename, struct ssh2_userkey *key,		  char *passphrase);int sshcom_encrypted(const Filename *filename, char **comment);struct ssh2_userkey *sshcom_read(const Filename *filename, char *passphrase);int sshcom_write(const Filename *filename, struct ssh2_userkey *key,		 char *passphrase);/* * Given a key type, determine whether we know how to import it. */int import_possible(int type){    if (type == SSH_KEYTYPE_OPENSSH)	return 1;    if (type == SSH_KEYTYPE_SSHCOM)	return 1;    return 0;}/* * Given a key type, determine what native key type * (SSH_KEYTYPE_SSH1 or SSH_KEYTYPE_SSH2) it will come out as once * we've imported it. */int import_target_type(int type){    /*     * There are no known foreign SSH1 key formats.     */    return SSH_KEYTYPE_SSH2;}/* * Determine whether a foreign key is encrypted. */int import_encrypted(const Filename *filename, int type, char **comment){    if (type == SSH_KEYTYPE_OPENSSH) {	/* OpenSSH doesn't do key comments */	*comment = dupstr(filename_to_str(filename));	return openssh_encrypted(filename);    }    if (type == SSH_KEYTYPE_SSHCOM) {	return sshcom_encrypted(filename, comment);    }    return 0;}/* * Import an SSH1 key. */int import_ssh1(const Filename *filename, int type,		struct RSAKey *key, char *passphrase){    return 0;}/* * Import an SSH2 key. */struct ssh2_userkey *import_ssh2(const Filename *filename, int type,				 char *passphrase){    if (type == SSH_KEYTYPE_OPENSSH)	return openssh_read(filename, passphrase);    if (type == SSH_KEYTYPE_SSHCOM)	return sshcom_read(filename, passphrase);    return NULL;}/* * Export an SSH1 key. */int export_ssh1(const Filename *filename, int type, struct RSAKey *key,		char *passphrase){    return 0;}/* * Export an SSH2 key. */int export_ssh2(const Filename *filename, int type,                struct ssh2_userkey *key, char *passphrase){    if (type == SSH_KEYTYPE_OPENSSH)	return openssh_write(filename, key, passphrase);    if (type == SSH_KEYTYPE_SSHCOM)	return sshcom_write(filename, key, passphrase);    return 0;}/* ---------------------------------------------------------------------- * Helper routines. (The base64 ones are defined in sshpubk.c.) */#define isbase64(c) (    ((c) >= 'A' && (c) <= 'Z') || \                         ((c) >= 'a' && (c) <= 'z') || \                         ((c) >= '0' && (c) <= '9') || \                         (c) == '+' || (c) == '/' || (c) == '=' \                         )/* * Read an ASN.1/BER identifier and length pair. *  * Flags are a combination of the #defines listed below. *  * Returns -1 if unsuccessful; otherwise returns the number of * bytes used out of the source data. *//* ASN.1 tag classes. */#define ASN1_CLASS_UNIVERSAL        (0 << 6)#define ASN1_CLASS_APPLICATION      (1 << 6)#define ASN1_CLASS_CONTEXT_SPECIFIC (2 << 6)#define ASN1_CLASS_PRIVATE          (3 << 6)#define ASN1_CLASS_MASK             (3 << 6)/* Primitive versus constructed bit. */#define ASN1_CONSTRUCTED            (1 << 5)static int ber_read_id_len(void *source, int sourcelen,			   int *id, int *length, int *flags){    unsigned char *p = (unsigned char *) source;    if (sourcelen == 0)	return -1;    *flags = (*p & 0xE0);    if ((*p & 0x1F) == 0x1F) {	*id = 0;	while (*p & 0x80) {	    p++, sourcelen--;	    if (sourcelen == 0)		return -1;	    *id = (*id << 7) | (*p & 0x7F);	}	p++, sourcelen--;    } else {	*id = *p & 0x1F;	p++, sourcelen--;    }    if (sourcelen == 0)	return -1;    if (*p & 0x80) {	int n = *p & 0x7F;	p++, sourcelen--;	if (sourcelen < n)	    return -1;	*length = 0;	while (n--)	    *length = (*length << 8) | (*p++);	sourcelen -= n;    } else {	*length = *p;	p++, sourcelen--;    }    return p - (unsigned char *) source;}/* * Write an ASN.1/BER identifier and length pair. Returns the * number of bytes consumed. Assumes dest contains enough space. * Will avoid writing anything if dest is NULL, but still return * amount of space required. */static int ber_write_id_len(void *dest, int id, int length, int flags){    unsigned char *d = (unsigned char *)dest;    int len = 0;    if (id <= 30) {	/*	 * Identifier is one byte.	 */	len++;	if (d) *d++ = id | flags;    } else {	int n;	/*	 * Identifier is multiple bytes: the first byte is 11111	 * plus the flags, and subsequent bytes encode the value of	 * the identifier, 7 bits at a time, with the top bit of	 * each byte 1 except the last one which is 0.	 */	len++;	if (d) *d++ = 0x1F | flags;	for (n = 1; (id >> (7*n)) > 0; n++)	    continue;		       /* count the bytes */	while (n--) {	    len++;	    if (d) *d++ = (n ? 0x80 : 0) | ((id >> (7*n)) & 0x7F);	}    }    if (length < 128) {	/*	 * Length is one byte.	 */	len++;	if (d) *d++ = length;    } else {	int n;	/*	 * Length is multiple bytes. The first is 0x80 plus the	 * number of subsequent bytes, and the subsequent bytes	 * encode the actual length.	 */	for (n = 1; (length >> (8*n)) > 0; n++)	    continue;		       /* count the bytes */	len++;	if (d) *d++ = 0x80 | n;	while (n--) {	    len++;	    if (d) *d++ = (length >> (8*n)) & 0xFF;	}    }    return len;}static int put_string(void *target, void *data, int len){    unsigned char *d = (unsigned char *)target;    PUT_32BIT(d, len);    memcpy(d+4, data, len);    return len+4;}static int put_mp(void *target, void *data, int len){    unsigned char *d = (unsigned char *)target;    unsigned char *i = (unsigned char *)data;    if (*i & 0x80) {        PUT_32BIT(d, len+1);        d[4] = 0;        memcpy(d+5, data, len);        return len+5;    } else {        PUT_32BIT(d, len);        memcpy(d+4, data, len);        return len+4;    }}/* Simple structure to point to an mp-int within a blob. */struct mpint_pos { void *start; int bytes; };static int ssh2_read_mpint(void *data, int len, struct mpint_pos *ret){    int bytes;    unsigned char *d = (unsigned char *) data;    if (len < 4)        goto error;    bytes = GET_32BIT(d);    if (len < 4+bytes)        goto error;    ret->start = d + 4;    ret->bytes = bytes;    return bytes+4;    error:    ret->start = NULL;    ret->bytes = -1;    return len;                        /* ensure further calls fail as well */}/* ---------------------------------------------------------------------- * Code to read and write OpenSSH private keys. */enum { OSSH_DSA, OSSH_RSA };struct openssh_key {    int type;    int encrypted;    char iv[32];    unsigned char *keyblob;    int keyblob_len, keyblob_size;};static struct openssh_key *load_openssh_key(const Filename *filename){    struct openssh_key *ret;    FILE *fp;    char buffer[256];    char *errmsg, *p;    int headers_done;    char base64_bit[4];    int base64_chars = 0;    ret = snew(struct openssh_key);    ret->keyblob = NULL;    ret->keyblob_len = ret->keyblob_size = 0;    ret->encrypted = 0;    memset(ret->iv, 0, sizeof(ret->iv));    fp = f_open(*filename, "r");    if (!fp) {	errmsg = "Unable to open key file";	goto error;    }    if (!fgets(buffer, sizeof(buffer), fp) ||	0 != strncmp(buffer, "-----BEGIN ", 11) ||	0 != strcmp(buffer+strlen(buffer)-17, "PRIVATE KEY-----\n")) {	errmsg = "File does not begin with OpenSSH key header";	goto error;    }    if (!strcmp(buffer, "-----BEGIN RSA PRIVATE KEY-----\n"))	ret->type = OSSH_RSA;    else if (!strcmp(buffer, "-----BEGIN DSA PRIVATE KEY-----\n"))	ret->type = OSSH_DSA;    else {	errmsg = "Unrecognised key type";	goto error;    }    headers_done = 0;    while (1) {	if (!fgets(buffer, sizeof(buffer), fp)) {	    errmsg = "Unexpected end of file";	    goto error;	}	if (0 == strncmp(buffer, "-----END ", 9) &&	    0 == strcmp(buffer+strlen(buffer)-17, "PRIVATE KEY-----\n"))	    break;		       /* done */	if ((p = strchr(buffer, ':')) != NULL) {	    if (headers_done) {		errmsg = "Header found in body of key data";		goto error;	    }	    *p++ = '\0';	    while (*p && isspace((unsigned char)*p)) p++;	    if (!strcmp(buffer, "Proc-Type")) {		if (p[0] != '4' || p[1] != ',') {		    errmsg = "Proc-Type is not 4 (only 4 is supported)";		    goto error;		}		p += 2;		if (!strcmp(p, "ENCRYPTED\n"))		    ret->encrypted = 1;	    } else if (!strcmp(buffer, "DEK-Info")) {		int i, j;		if (strncmp(p, "DES-EDE3-CBC,", 13)) {		    errmsg = "Ciphers other than DES-EDE3-CBC not supported";		    goto error;		}		p += 13;		for (i = 0; i < 8; i++) {		    if (1 != sscanf(p, "%2x", &j))			break;		    ret->iv[i] = j;		    p += 2;		}		if (i < 8) {		    errmsg = "Expected 16-digit iv in DEK-Info";		    goto error;		}	    }	} else {	    headers_done = 1;	    p = buffer;	    while (isbase64(*p)) {                base64_bit[base64_chars++] = *p;                if (base64_chars == 4) {                    unsigned char out[3];                    int len;                    base64_chars = 0;

⌨️ 快捷键说明

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