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

📄 sshrsa.c

📁 大名鼎鼎的远程登录软件putty的Symbian版源码
💻 C
📖 第 1 页 / 共 2 页
字号:
void freersakey(struct RSAKey *key){    if (key->modulus)	freebn(key->modulus);    if (key->exponent)	freebn(key->exponent);    if (key->private_exponent)	freebn(key->private_exponent);    if (key->comment)	sfree(key->comment);}/* ---------------------------------------------------------------------- * Implementation of the ssh-rsa signing key type.  */static void getstring(char **data, int *datalen, char **p, int *length){    *p = NULL;    if (*datalen < 4)	return;    *length = GET_32BIT(*data);    *datalen -= 4;    *data += 4;    if (*datalen < *length)	return;    *p = *data;    *data += *length;    *datalen -= *length;}static Bignum getmp(char **data, int *datalen){    char *p;    int length;    Bignum b;    getstring(data, datalen, &p, &length);    if (!p)	return NULL;    b = bignum_from_bytes((unsigned char *)p, length);    return b;}static void *rsa2_newkey(char *data, int len){    char *p;    int slen;    struct RSAKey *rsa;    rsa = snew(struct RSAKey);    if (!rsa)	return NULL;    getstring(&data, &len, &p, &slen);    if (!p || slen != 7 || memcmp(p, "ssh-rsa", 7)) {	sfree(rsa);	return NULL;    }    rsa->exponent = getmp(&data, &len);    rsa->modulus = getmp(&data, &len);    rsa->private_exponent = NULL;    rsa->comment = NULL;    return rsa;}static void rsa2_freekey(void *key){    struct RSAKey *rsa = (struct RSAKey *) key;    freersakey(rsa);    sfree(rsa);}static char *rsa2_fmtkey(void *key){    struct RSAKey *rsa = (struct RSAKey *) key;    char *p;    int len;    len = rsastr_len(rsa);    p = snewn(len, char);    rsastr_fmt(p, rsa);    return p;}static unsigned char *rsa2_public_blob(void *key, int *len){    struct RSAKey *rsa = (struct RSAKey *) key;    int elen, mlen, bloblen;    int i;    unsigned char *blob, *p;    elen = (bignum_bitcount(rsa->exponent) + 8) / 8;    mlen = (bignum_bitcount(rsa->modulus) + 8) / 8;    /*     * string "ssh-rsa", mpint exp, mpint mod. Total 19+elen+mlen.     * (three length fields, 12+7=19).     */    bloblen = 19 + elen + mlen;    blob = snewn(bloblen, unsigned char);    p = blob;    PUT_32BIT(p, 7);    p += 4;    memcpy(p, "ssh-rsa", 7);    p += 7;    PUT_32BIT(p, elen);    p += 4;    for (i = elen; i--;)	*p++ = bignum_byte(rsa->exponent, i);    PUT_32BIT(p, mlen);    p += 4;    for (i = mlen; i--;)	*p++ = bignum_byte(rsa->modulus, i);    assert(p == blob + bloblen);    *len = bloblen;    return blob;}static unsigned char *rsa2_private_blob(void *key, int *len){    struct RSAKey *rsa = (struct RSAKey *) key;    int dlen, plen, qlen, ulen, bloblen;    int i;    unsigned char *blob, *p;    dlen = (bignum_bitcount(rsa->private_exponent) + 8) / 8;    plen = (bignum_bitcount(rsa->p) + 8) / 8;    qlen = (bignum_bitcount(rsa->q) + 8) / 8;    ulen = (bignum_bitcount(rsa->iqmp) + 8) / 8;    /*     * mpint private_exp, mpint p, mpint q, mpint iqmp. Total 16 +     * sum of lengths.     */    bloblen = 16 + dlen + plen + qlen + ulen;    blob = snewn(bloblen, unsigned char);    p = blob;    PUT_32BIT(p, dlen);    p += 4;    for (i = dlen; i--;)	*p++ = bignum_byte(rsa->private_exponent, i);    PUT_32BIT(p, plen);    p += 4;    for (i = plen; i--;)	*p++ = bignum_byte(rsa->p, i);    PUT_32BIT(p, qlen);    p += 4;    for (i = qlen; i--;)	*p++ = bignum_byte(rsa->q, i);    PUT_32BIT(p, ulen);    p += 4;    for (i = ulen; i--;)	*p++ = bignum_byte(rsa->iqmp, i);    assert(p == blob + bloblen);    *len = bloblen;    return blob;}static void *rsa2_createkey(unsigned char *pub_blob, int pub_len,			    unsigned char *priv_blob, int priv_len){    struct RSAKey *rsa;    char *pb = (char *) priv_blob;    rsa = rsa2_newkey((char *) pub_blob, pub_len);    rsa->private_exponent = getmp(&pb, &priv_len);    rsa->p = getmp(&pb, &priv_len);    rsa->q = getmp(&pb, &priv_len);    rsa->iqmp = getmp(&pb, &priv_len);    if (!rsa_verify(rsa)) {	rsa2_freekey(rsa);	return NULL;    }    return rsa;}static void *rsa2_openssh_createkey(unsigned char **blob, int *len){    char **b = (char **) blob;    struct RSAKey *rsa;    rsa = snew(struct RSAKey);    if (!rsa)	return NULL;    rsa->comment = NULL;    rsa->modulus = getmp(b, len);    rsa->exponent = getmp(b, len);    rsa->private_exponent = getmp(b, len);    rsa->iqmp = getmp(b, len);    rsa->p = getmp(b, len);    rsa->q = getmp(b, len);    if (!rsa->modulus || !rsa->exponent || !rsa->private_exponent ||	!rsa->iqmp || !rsa->p || !rsa->q) {	sfree(rsa->modulus);	sfree(rsa->exponent);	sfree(rsa->private_exponent);	sfree(rsa->iqmp);	sfree(rsa->p);	sfree(rsa->q);	sfree(rsa);	return NULL;    }    return rsa;}static int rsa2_openssh_fmtkey(void *key, unsigned char *blob, int len){    struct RSAKey *rsa = (struct RSAKey *) key;    int bloblen, i;    bloblen =	ssh2_bignum_length(rsa->modulus) +	ssh2_bignum_length(rsa->exponent) +	ssh2_bignum_length(rsa->private_exponent) +	ssh2_bignum_length(rsa->iqmp) +	ssh2_bignum_length(rsa->p) + ssh2_bignum_length(rsa->q);    if (bloblen > len)	return bloblen;    bloblen = 0;#define ENC(x) \    PUT_32BIT(blob+bloblen, ssh2_bignum_length((x))-4); bloblen += 4; \    for (i = ssh2_bignum_length((x))-4; i-- ;) blob[bloblen++]=bignum_byte((x),i);    ENC(rsa->modulus);    ENC(rsa->exponent);    ENC(rsa->private_exponent);    ENC(rsa->iqmp);    ENC(rsa->p);    ENC(rsa->q);    return bloblen;}static int rsa2_pubkey_bits(void *blob, int len){    struct RSAKey *rsa;    int ret;    rsa = rsa2_newkey((char *) blob, len);    ret = bignum_bitcount(rsa->modulus);    rsa2_freekey(rsa);    return ret;}static char *rsa2_fingerprint(void *key){    struct RSAKey *rsa = (struct RSAKey *) key;    struct MD5Context md5c;    unsigned char digest[16], lenbuf[4];    char buffer[16 * 3 + 40];    char *ret;    int numlen, i;    MD5Init(&md5c);    MD5Update(&md5c, (unsigned char *)"\0\0\0\7ssh-rsa", 11);#define ADD_BIGNUM(bignum) \    numlen = (bignum_bitcount(bignum)+8)/8; \    PUT_32BIT(lenbuf, numlen); MD5Update(&md5c, lenbuf, 4); \    for (i = numlen; i-- ;) { \        unsigned char c = bignum_byte(bignum, i); \        MD5Update(&md5c, &c, 1); \    }    ADD_BIGNUM(rsa->exponent);    ADD_BIGNUM(rsa->modulus);#undef ADD_BIGNUM    MD5Final(digest, &md5c);    sprintf(buffer, "ssh-rsa %d ", bignum_bitcount(rsa->modulus));    for (i = 0; i < 16; i++)	sprintf(buffer + strlen(buffer), "%s%02x", i ? ":" : "",		digest[i]);    ret = snewn(strlen(buffer) + 1, char);    if (ret)	strcpy(ret, buffer);    return ret;}/* * This is the magic ASN.1/DER prefix that goes in the decoded * signature, between the string of FFs and the actual SHA hash * value. The meaning of it is: *  * 00 -- this marks the end of the FFs; not part of the ASN.1 bit itself *  * 30 21 -- a constructed SEQUENCE of length 0x21 *    30 09 -- a constructed sub-SEQUENCE of length 9 *       06 05 -- an object identifier, length 5 *          2B 0E 03 02 1A -- object id { 1 3 14 3 2 26 } *                            (the 1,3 comes from 0x2B = 43 = 40*1+3) *       05 00 -- NULL *    04 14 -- a primitive OCTET STRING of length 0x14 *       [0x14 bytes of hash data follows] *  * The object id in the middle there is listed as `id-sha1' in * ftp://ftp.rsasecurity.com/pub/pkcs/pkcs-1/pkcs-1v2-1d2.asn (the * ASN module for PKCS #1) and its expanded form is as follows: *  * id-sha1                OBJECT IDENTIFIER ::= { *    iso(1) identified-organization(3) oiw(14) secsig(3) *    algorithms(2) 26 } */static const unsigned char asn1_weird_stuff[] = {    0x00, 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2B,    0x0E, 0x03, 0x02, 0x1A, 0x05, 0x00, 0x04, 0x14,};#define ASN1_LEN ( (int) sizeof(asn1_weird_stuff) )static int rsa2_verifysig(void *key, char *sig, int siglen,			  char *data, int datalen){    struct RSAKey *rsa = (struct RSAKey *) key;    Bignum in, out;    char *p;    int slen;    int bytes, i, j, ret;    unsigned char hash[20];    getstring(&sig, &siglen, &p, &slen);    if (!p || slen != 7 || memcmp(p, "ssh-rsa", 7)) {	return 0;    }    in = getmp(&sig, &siglen);    out = modpow(in, rsa->exponent, rsa->modulus);    freebn(in);    ret = 1;    bytes = (bignum_bitcount(rsa->modulus)+7) / 8;    /* Top (partial) byte should be zero. */    if (bignum_byte(out, bytes - 1) != 0)	ret = 0;    /* First whole byte should be 1. */    if (bignum_byte(out, bytes - 2) != 1)	ret = 0;    /* Most of the rest should be FF. */    for (i = bytes - 3; i >= 20 + ASN1_LEN; i--) {	if (bignum_byte(out, i) != 0xFF)	    ret = 0;    }    /* Then we expect to see the asn1_weird_stuff. */    for (i = 20 + ASN1_LEN - 1, j = 0; i >= 20; i--, j++) {	if (bignum_byte(out, i) != asn1_weird_stuff[j])	    ret = 0;    }    /* Finally, we expect to see the SHA-1 hash of the signed data. */    SHA_Simple(data, datalen, hash);    for (i = 19, j = 0; i >= 0; i--, j++) {	if (bignum_byte(out, i) != hash[j])	    ret = 0;    }    freebn(out);    return ret;}static unsigned char *rsa2_sign(void *key, char *data, int datalen,				int *siglen){    struct RSAKey *rsa = (struct RSAKey *) key;    unsigned char *bytes;    int nbytes;    unsigned char hash[20];    Bignum in, out;    int i, j;    SHA_Simple(data, datalen, hash);    nbytes = (bignum_bitcount(rsa->modulus) - 1) / 8;    bytes = snewn(nbytes, unsigned char);    bytes[0] = 1;    for (i = 1; i < nbytes - 20 - ASN1_LEN; i++)	bytes[i] = 0xFF;    for (i = nbytes - 20 - ASN1_LEN, j = 0; i < nbytes - 20; i++, j++)	bytes[i] = asn1_weird_stuff[j];    for (i = nbytes - 20, j = 0; i < nbytes; i++, j++)	bytes[i] = hash[j];    in = bignum_from_bytes(bytes, nbytes);    sfree(bytes);    out = rsa_privkey_op(in, rsa);    freebn(in);    nbytes = (bignum_bitcount(out) + 7) / 8;    bytes = snewn(4 + 7 + 4 + nbytes, unsigned char);    PUT_32BIT(bytes, 7);    memcpy(bytes + 4, "ssh-rsa", 7);    PUT_32BIT(bytes + 4 + 7, nbytes);    for (i = 0; i < nbytes; i++)	bytes[4 + 7 + 4 + i] = bignum_byte(out, nbytes - 1 - i);    freebn(out);    *siglen = 4 + 7 + 4 + nbytes;    return bytes;}const struct ssh_signkey ssh_rsa = {    rsa2_newkey,    rsa2_freekey,    rsa2_fmtkey,    rsa2_public_blob,    rsa2_private_blob,    rsa2_createkey,    rsa2_openssh_createkey,    rsa2_openssh_fmtkey,    rsa2_pubkey_bits,    rsa2_fingerprint,    rsa2_verifysig,    rsa2_sign,    "ssh-rsa",    "rsa2"};

⌨️ 快捷键说明

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