Exemplo n.º 1
0
int makekey(unsigned char *data, struct RSAKey *result,
		unsigned char **keystr, int order)
{
	unsigned char *p = data;
	int i;

	if (result) {
		result->bits = 0;
		for (i = 0; i < 4; i++)
			result->bits = (result->bits << 8) + *p++;
	} else
		p += 4;

	/*
	 * order=0 means exponent then modulus (the keys sent by the
	 * server). order=1 means modulus then exponent (the keys
	 * stored in a keyfile).
	 */

	if (order == 0)
		p += ssh1_read_bignum(p, result ? &result->exponent : NULL);
	if (result)
		result->bytes = (((p[0] << 8) + p[1]) + 7) / 8;
	if (keystr)
		*keystr = p + 2;
	p += ssh1_read_bignum(p, result ? &result->modulus : NULL);
	if (order == 1)
		p += ssh1_read_bignum(p, result ? &result->exponent : NULL);

	return p - data;
}
Exemplo n.º 2
0
int makekey(unsigned char *data, int len, struct RSAKey *result,
	    unsigned char **keystr, int order)
{
    unsigned char *p = data;
    int i, n;

    if (len < 4)
	return -1;

    if (result) {
	result->bits = 0;
	for (i = 0; i < 4; i++)
	    result->bits = (result->bits << 8) + *p++;
    } else
	p += 4;

    len -= 4;

    /*
     * order=0 means exponent then modulus (the keys sent by the
     * server). order=1 means modulus then exponent (the keys
     * stored in a keyfile).
     */

    if (order == 0) {
	n = ssh1_read_bignum(p, len, result ? &result->exponent : NULL);
	if (n < 0) return -1;
	p += n;
	len -= n;
    }

    n = ssh1_read_bignum(p, len, result ? &result->modulus : NULL);
    if (n < 0 || (result && bignum_bitcount(result->modulus) == 0)) return -1;
    if (result)
	result->bytes = n - 2;
    if (keystr)
	*keystr = p + 2;
    p += n;
    len -= n;

    if (order == 1) {
	n = ssh1_read_bignum(p, len, result ? &result->exponent : NULL);
	if (n < 0) return -1;
	p += n;
	len -= n;
    }
    return p - data;
}
Exemplo n.º 3
0
/* Given a public blob, determine its length. */
int rsa_public_blob_len(void *data, int maxlen)
{
    unsigned char *p = (unsigned char *)data;
    int n;

    if (maxlen < 4)
	return -1;
    p += 4;			       /* length word */
    maxlen -= 4;

    n = ssh1_read_bignum(p, maxlen, NULL);    /* exponent */
    if (n < 0)
	return -1;
    p += n;

    n = ssh1_read_bignum(p, maxlen, NULL);    /* modulus */
    if (n < 0)
	return -1;
    p += n;

    return p - (unsigned char *)data;
}
Exemplo n.º 4
0
/*
 * DH stage 1: invent a number x between 1 and q, and compute e =
 * g^x mod p. Return e.
 * 
 * If `nbits' is greater than zero, it is used as an upper limit
 * for the number of bits in x. This is safe provided that (a) you
 * use twice as many bits in x as the number of bits you expect to
 * use in your session key, and (b) the DH group is a safe prime
 * (which SSH demands that it must be).
 * 
 * P. C. van Oorschot, M. J. Wiener
 * "On Diffie-Hellman Key Agreement with Short Exponents".
 * Advances in Cryptology: Proceedings of Eurocrypt '96
 * Springer-Verlag, May 1996.
 */
Bignum dh_create_e(void *handle, int nbits)
{
    struct dh_ctx *ctx = (struct dh_ctx *)handle;
    int i;

    int nbytes;
    unsigned char *buf;

    nbytes = ssh1_bignum_length(ctx->qmask);
    buf = snewn(nbytes, unsigned char);

    do {
	/*
	 * Create a potential x, by ANDing a string of random bytes
	 * with qmask.
	 */
	if (ctx->x)
	    freebn(ctx->x);
	if (nbits == 0 || nbits > bignum_bitcount(ctx->qmask)) {
	    ssh1_write_bignum(buf, ctx->qmask);
	    for (i = 2; i < nbytes; i++)
		buf[i] &= random_byte();
	    ssh1_read_bignum(buf, nbytes, &ctx->x);   /* can't fail */
	} else {
	    int b, nb;
	    ctx->x = bn_power_2(nbits);
	    b = nb = 0;
	    for (i = 0; i < nbits; i++) {
		if (nb == 0) {
		    nb = 8;
		    b = random_byte();
		}
		bignum_set_bit(ctx->x, i, b & 1);
		b >>= 1;
		nb--;
	    }
	}
    } while (bignum_cmp(ctx->x, One) <= 0 || bignum_cmp(ctx->x, ctx->q) >= 0);

    sfree(buf);

    /*
     * Done. Now compute e = g^x mod p.
     */
    ctx->e = modpow(ctx->g, ctx->x, ctx->p);

    return ctx->e;
}
Exemplo n.º 5
0
static int loadrsakey_main(FILE * fp, struct RSAKey *key, int pub_only,
			   char **commentptr, char *passphrase,
			   const char **error)
{
    unsigned char buf[16384];
    unsigned char keybuf[16];
    int len;
    int i, j, ciphertype;
    int ret = 0;
    struct MD5Context md5c;
    char *comment;

    *error = NULL;

    /* Slurp the whole file (minus the header) into a buffer. */
    len = fread(buf, 1, sizeof(buf), fp);
    fclose(fp);
    if (len < 0 || len == sizeof(buf)) {
	*error = "error reading file";
	goto end;		       /* file too big or not read */
    }

    i = 0;
    *error = "file format error";

    /*
     * A zero byte. (The signature includes a terminating NUL.)
     */
    if (len - i < 1 || buf[i] != 0)
	goto end;
    i++;

    /* One byte giving encryption type, and one reserved uint32. */
    if (len - i < 1)
	goto end;
    ciphertype = buf[i];
    if (ciphertype != 0 && ciphertype != SSH_CIPHER_3DES)
	goto end;
    i++;
    if (len - i < 4)
	goto end;		       /* reserved field not present */
    if (buf[i] != 0 || buf[i + 1] != 0 || buf[i + 2] != 0
	|| buf[i + 3] != 0) goto end;  /* reserved field nonzero, panic! */
    i += 4;

    /* Now the serious stuff. An ordinary SSH-1 public key. */
    j = makekey(buf + i, len - i, key, NULL, 1);
    if (j < 0)
	goto end;		       /* overran */
    i += j;

    /* Next, the comment field. */
    j = toint(GET_32BIT(buf + i));
    i += 4;
    if (j < 0 || len - i < j)
	goto end;
    comment = snewn(j + 1, char);
    if (comment) {
	memcpy(comment, buf + i, j);
	comment[j] = '\0';
    }
    i += j;
    if (commentptr)
	*commentptr = dupstr(comment);
    if (key)
	key->comment = comment;
    else
	sfree(comment);

    if (pub_only) {
	ret = 1;
	goto end;
    }

    if (!key) {
	ret = ciphertype != 0;
	*error = NULL;
	goto end;
    }

    /*
     * Decrypt remainder of buffer.
     */
    if (ciphertype) {
	MD5Init(&md5c);
	MD5Update(&md5c, (unsigned char *)passphrase, strlen(passphrase));
	MD5Final(keybuf, &md5c);
	des3_decrypt_pubkey(keybuf, buf + i, (len - i + 7) & ~7);
	smemclr(keybuf, sizeof(keybuf));	/* burn the evidence */
    }

    /*
     * We are now in the secret part of the key. The first four
     * bytes should be of the form a, b, a, b.
     */
    if (len - i < 4)
	goto end;
    if (buf[i] != buf[i + 2] || buf[i + 1] != buf[i + 3]) {
	*error = "wrong passphrase";
	ret = -1;
	goto end;
    }
    i += 4;

    /*
     * After that, we have one further bignum which is our
     * decryption exponent, and then the three auxiliary values
     * (iqmp, q, p).
     */
    j = makeprivate(buf + i, len - i, key);
    if (j < 0) goto end;
    i += j;
    j = ssh1_read_bignum(buf + i, len - i, &key->iqmp);
    if (j < 0) goto end;
    i += j;
    j = ssh1_read_bignum(buf + i, len - i, &key->q);
    if (j < 0) goto end;
    i += j;
    j = ssh1_read_bignum(buf + i, len - i, &key->p);
    if (j < 0) goto end;
    i += j;

    if (!rsa_verify(key)) {
	*error = "rsa_verify failed";
	freersakey(key);
	ret = 0;
    } else
	ret = 1;

  end:
    smemclr(buf, sizeof(buf));       /* burn the evidence */
    return ret;
}
Exemplo n.º 6
0
int makeprivate(unsigned char *data, int len, struct RSAKey *result)
{
    return ssh1_read_bignum(data, len, &result->private_exponent);
}