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

📄 import.c

📁 大名鼎鼎的远程登录软件putty的Symbian版源码
💻 C
📖 第 1 页 / 共 4 页
字号:
        errmsg = "Key blob does not contain a key type string";        goto error;    }    if (len > sizeof(prefix_rsa) - 1 &&        !memcmp(key->keyblob+pos+4, prefix_rsa, sizeof(prefix_rsa) - 1)) {        type = RSA;    } else if (len > sizeof(prefix_dsa) - 1 &&        !memcmp(key->keyblob+pos+4, prefix_dsa, sizeof(prefix_dsa) - 1)) {        type = DSA;    } else {        errmsg = "Key is of unknown type";        goto error;    }    pos += 4+len;    /*     * Determine the cipher type.     */    if (key->keyblob_len < pos+4 ||        (len = GET_32BIT(key->keyblob + pos)) > key->keyblob_len - pos - 4) {        errmsg = "Key blob does not contain a cipher type string";        goto error;    }    if (len == 4 && !memcmp(key->keyblob+pos+4, "none", 4))        encrypted = 0;    else if (len == 8 && !memcmp(key->keyblob+pos+4, "3des-cbc", 8))        encrypted = 1;    else {        errmsg = "Key encryption is of unknown type";        goto error;    }    pos += 4+len;    /*     * Get hold of the encrypted part of the key.     */    if (key->keyblob_len < pos+4 ||        (len = GET_32BIT(key->keyblob + pos)) > key->keyblob_len - pos - 4) {        errmsg = "Key blob does not contain actual key data";        goto error;    }    ciphertext = (char *)key->keyblob + pos + 4;    cipherlen = len;    if (cipherlen == 0) {        errmsg = "Length of key data is zero";        goto error;    }    /*     * Decrypt it if necessary.     */    if (encrypted) {	/*	 * Derive encryption key from passphrase and iv/salt:	 * 	 *  - let block A equal MD5(passphrase)	 *  - let block B equal MD5(passphrase || A)	 *  - block C would be MD5(passphrase || A || B) and so on	 *  - encryption key is the first N bytes of A || B	 */	struct MD5Context md5c;	unsigned char keybuf[32], iv[8];        if (cipherlen % 8 != 0) {            errmsg = "Encrypted part of key is not a multiple of cipher block"                " size";            goto error;        }	MD5Init(&md5c);	MD5Update(&md5c, (unsigned char *)passphrase, strlen(passphrase));	MD5Final(keybuf, &md5c);	MD5Init(&md5c);	MD5Update(&md5c, (unsigned char *)passphrase, strlen(passphrase));	MD5Update(&md5c, keybuf, 16);	MD5Final(keybuf+16, &md5c);	/*	 * Now decrypt the key blob.	 */        memset(iv, 0, sizeof(iv));	des3_decrypt_pubkey_ossh(keybuf, iv, (unsigned char *)ciphertext,				 cipherlen);        memset(&md5c, 0, sizeof(md5c));        memset(keybuf, 0, sizeof(keybuf));        /*         * Hereafter we return WRONG_PASSPHRASE for any parsing         * error. (But only if we've just tried to decrypt it!         * Returning WRONG_PASSPHRASE for an unencrypted key is         * automatic doom.)         */        if (encrypted)            ret = SSH2_WRONG_PASSPHRASE;    }    /*     * Strip away the containing string to get to the real meat.     */    len = GET_32BIT(ciphertext);    if (len < 0 || len > cipherlen-4) {        errmsg = "containing string was ill-formed";        goto error;    }    ciphertext += 4;    cipherlen = len;    /*     * Now we break down into RSA versus DSA. In either case we'll     * construct public and private blobs in our own format, and     * end up feeding them to alg->createkey().     */    blobsize = cipherlen + 256;    blob = snewn(blobsize, unsigned char);    privlen = 0;    if (type == RSA) {        struct mpint_pos n, e, d, u, p, q;        int pos = 0;        pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &e);        pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &d);        pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &n);        pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &u);        pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &p);        pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &q);        if (!q.start) {            errmsg = "key data did not contain six integers";            goto error;        }        alg = &ssh_rsa;        pos = 0;        pos += put_string(blob+pos, "ssh-rsa", 7);        pos += put_mp(blob+pos, e.start, e.bytes);        pos += put_mp(blob+pos, n.start, n.bytes);        publen = pos;        pos += put_string(blob+pos, d.start, d.bytes);        pos += put_mp(blob+pos, q.start, q.bytes);        pos += put_mp(blob+pos, p.start, p.bytes);        pos += put_mp(blob+pos, u.start, u.bytes);        privlen = pos - publen;    } else if (type == DSA) {        struct mpint_pos p, q, g, x, y;        int pos = 4;        if (GET_32BIT(ciphertext) != 0) {            errmsg = "predefined DSA parameters not supported";            goto error;        }        pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &p);        pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &g);        pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &q);        pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &y);        pos += sshcom_read_mpint(ciphertext+pos, cipherlen-pos, &x);        if (!x.start) {            errmsg = "key data did not contain five integers";            goto error;        }        alg = &ssh_dss;        pos = 0;        pos += put_string(blob+pos, "ssh-dss", 7);        pos += put_mp(blob+pos, p.start, p.bytes);        pos += put_mp(blob+pos, q.start, q.bytes);        pos += put_mp(blob+pos, g.start, g.bytes);        pos += put_mp(blob+pos, y.start, y.bytes);        publen = pos;        pos += put_mp(blob+pos, x.start, x.bytes);        privlen = pos - publen;    } else	return NULL;    assert(privlen > 0);	       /* should have bombed by now if not */    retkey = snew(struct ssh2_userkey);    retkey->alg = alg;    retkey->data = alg->createkey(blob, publen, blob+publen, privlen);    if (!retkey->data) {	sfree(retkey);	errmsg = "unable to create key data structure";	goto error;    }    retkey->comment = dupstr(key->comment);    errmsg = NULL; /* no error */    ret = retkey;    error:    if (blob) {        memset(blob, 0, blobsize);        sfree(blob);    }    memset(key->keyblob, 0, key->keyblob_size);    sfree(key->keyblob);    memset(&key, 0, sizeof(key));    sfree(key);    return ret;}int sshcom_write(const Filename *filename, struct ssh2_userkey *key,		 char *passphrase){    unsigned char *pubblob, *privblob;    int publen, privlen;    unsigned char *outblob;    int outlen;    struct mpint_pos numbers[6];    int nnumbers, initial_zero, pos, lenpos, i;    char *type;    char *ciphertext;    int cipherlen;    int ret = 0;    FILE *fp;    /*     * Fetch the key blobs.     */    pubblob = key->alg->public_blob(key->data, &publen);    privblob = key->alg->private_blob(key->data, &privlen);    outblob = NULL;    /*     * Find the sequence of integers to be encoded into the OpenSSH     * key blob, and also decide on the header line.     */    if (key->alg == &ssh_rsa) {        int pos;        struct mpint_pos n, e, d, p, q, iqmp;        pos = 4 + GET_32BIT(pubblob);        pos += ssh2_read_mpint(pubblob+pos, publen-pos, &e);        pos += ssh2_read_mpint(pubblob+pos, publen-pos, &n);        pos = 0;        pos += ssh2_read_mpint(privblob+pos, privlen-pos, &d);        pos += ssh2_read_mpint(privblob+pos, privlen-pos, &p);        pos += ssh2_read_mpint(privblob+pos, privlen-pos, &q);        pos += ssh2_read_mpint(privblob+pos, privlen-pos, &iqmp);        assert(e.start && iqmp.start); /* can't go wrong */        numbers[0] = e;        numbers[1] = d;        numbers[2] = n;        numbers[3] = iqmp;        numbers[4] = q;        numbers[5] = p;        nnumbers = 6;	initial_zero = 0;	type = "if-modn{sign{rsa-pkcs1-sha1},encrypt{rsa-pkcs1v2-oaep}}";    } else if (key->alg == &ssh_dss) {        int pos;        struct mpint_pos p, q, g, y, x;        pos = 4 + GET_32BIT(pubblob);        pos += ssh2_read_mpint(pubblob+pos, publen-pos, &p);        pos += ssh2_read_mpint(pubblob+pos, publen-pos, &q);        pos += ssh2_read_mpint(pubblob+pos, publen-pos, &g);        pos += ssh2_read_mpint(pubblob+pos, publen-pos, &y);        pos = 0;        pos += ssh2_read_mpint(privblob+pos, privlen-pos, &x);        assert(y.start && x.start); /* can't go wrong */        numbers[0] = p;        numbers[1] = g;        numbers[2] = q;        numbers[3] = y;        numbers[4] = x;        nnumbers = 5;	initial_zero = 1;	type = "dl-modp{sign{dsa-nist-sha1},dh{plain}}";    } else {        assert(0);                     /* zoinks! */    }    /*     * Total size of key blob will be somewhere under 512 plus     * combined length of integers. We'll calculate the more     * precise size as we construct the blob.     */    outlen = 512;    for (i = 0; i < nnumbers; i++)	outlen += 4 + numbers[i].bytes;    outblob = snewn(outlen, unsigned char);    /*     * Create the unencrypted key blob.     */    pos = 0;    PUT_32BIT(outblob+pos, SSHCOM_MAGIC_NUMBER); pos += 4;    pos += 4;			       /* length field, fill in later */    pos += put_string(outblob+pos, type, strlen(type));    {	char *ciphertype = passphrase ? "3des-cbc" : "none";	pos += put_string(outblob+pos, ciphertype, strlen(ciphertype));    }    lenpos = pos;		       /* remember this position */    pos += 4;			       /* encrypted-blob size */    pos += 4;			       /* encrypted-payload size */    if (initial_zero) {	PUT_32BIT(outblob+pos, 0);	pos += 4;    }    for (i = 0; i < nnumbers; i++)	pos += sshcom_put_mpint(outblob+pos,				numbers[i].start, numbers[i].bytes);    /* Now wrap up the encrypted payload. */    PUT_32BIT(outblob+lenpos+4, pos - (lenpos+8));    /* Pad encrypted blob to a multiple of cipher block size. */    if (passphrase) {	int padding = -(pos - (lenpos+4)) & 7;	while (padding--)	    outblob[pos++] = random_byte();    }    ciphertext = (char *)outblob+lenpos+4;    cipherlen = pos - (lenpos+4);    assert(!passphrase || cipherlen % 8 == 0);    /* Wrap up the encrypted blob string. */    PUT_32BIT(outblob+lenpos, cipherlen);    /* And finally fill in the total length field. */    PUT_32BIT(outblob+4, pos);    assert(pos < outlen);    /*     * Encrypt the key.     */    if (passphrase) {	/*	 * Derive encryption key from passphrase and iv/salt:	 * 	 *  - let block A equal MD5(passphrase)	 *  - let block B equal MD5(passphrase || A)	 *  - block C would be MD5(passphrase || A || B) and so on	 *  - encryption key is the first N bytes of A || B	 */	struct MD5Context md5c;	unsigned char keybuf[32], iv[8];	MD5Init(&md5c);	MD5Update(&md5c, (unsigned char *)passphrase, strlen(passphrase));	MD5Final(keybuf, &md5c);	MD5Init(&md5c);	MD5Update(&md5c, (unsigned char *)passphrase, strlen(passphrase));	MD5Update(&md5c, keybuf, 16);	MD5Final(keybuf+16, &md5c);	/*	 * Now decrypt the key blob.	 */        memset(iv, 0, sizeof(iv));	des3_encrypt_pubkey_ossh(keybuf, iv, (unsigned char *)ciphertext,				 cipherlen);        memset(&md5c, 0, sizeof(md5c));        memset(keybuf, 0, sizeof(keybuf));    }    /*     * And save it. We'll use Unix line endings just in case it's     * subsequently transferred in binary mode.     */    fp = f_open(*filename, "wb");      /* ensure Unix line endings */    if (!fp)	goto error;    fputs("---- BEGIN SSH2 ENCRYPTED PRIVATE KEY ----\n", fp);    fprintf(fp, "Comment: \"");    /*     * Comment header is broken with backslash-newline if it goes     * over 70 chars. Although it's surrounded by quotes, it     * _doesn't_ escape backslashes or quotes within the string.     * Don't ask me, I didn't design it.     */    {	int slen = 60;		       /* starts at 60 due to "Comment: " */	char *c = key->comment;	while ((int)strlen(c) > slen) {	    fprintf(fp, "%.*s\\\n", slen, c);	    c += slen;	    slen = 70;		       /* allow 70 chars on subsequent lines */	}	fprintf(fp, "%s\"\n", c);    }    base64_encode(fp, outblob, pos, 70);    fputs("---- END SSH2 ENCRYPTED PRIVATE KEY ----\n", fp);    fclose(fp);    ret = 1;    error:    if (outblob) {        memset(outblob, 0, outlen);        sfree(outblob);    }    if (privblob) {        memset(privblob, 0, privlen);        sfree(privblob);    }    if (pubblob) {        memset(pubblob, 0, publen);        sfree(pubblob);    }    return ret;}

⌨️ 快捷键说明

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