예제 #1
0
파일: ecc.c 프로젝트: grobe0ba/plan9front
void
ecdsasign(ECdomain *dom, ECpriv *priv, uchar *dig, int len, mpint *r, mpint *s)
{
	ECpriv tmp;
	mpint *E, *t;

	tmp.x = mpnew(0);
	tmp.y = mpnew(0);
	tmp.d = mpnew(0);
	E = betomp(dig, len, nil);
	t = mpnew(0);
	if(mpsignif(dom->n) < 8*len)
		mpright(E, 8*len - mpsignif(dom->n), E);
	for(;;){
		ecgen(dom, &tmp);
		mpmod(tmp.x, dom->n, r);
		if(mpcmp(r, mpzero) == 0)
			continue;
		mpmul(r, priv->d, s);
		mpadd(E, s, s);
		mpinvert(tmp.d, dom->n, t);
		mpmul(s, t, s);
		mpmod(s, dom->n, s);
		if(mpcmp(s, mpzero) != 0)
			break;
	}
	mpfree(t);
	mpfree(E);
	mpfree(tmp.x);
	mpfree(tmp.y);
	mpfree(tmp.d);
}
예제 #2
0
파일: rsaalg.c 프로젝트: BGCX261/znos-git
/* generate an rsa secret key with same params as a public key */
static void*
rsa_genfrompk(void *vpub)
{
	RSApub *pub;

	pub = vpub;
	return rsagen(mpsignif(pub->n), mpsignif(pub->ek), 0);
}
예제 #3
0
파일: cmsg.c 프로젝트: Earnestly/plan9
static void
send_ssh_cmsg_session_key(Conn *c)
{
	int i, n, buflen, serverkeylen, hostkeylen;
	mpint *b;
	uchar *buf;
	Msg *m;
	RSApub *ksmall, *kbig;

	m = allocmsg(c, SSH_CMSG_SESSION_KEY, 2048);
	putbyte(m, c->cipher->id);
	putbytes(m, c->cookie, COOKIELEN);

	serverkeylen = mpsignif(c->serverkey->n);
	hostkeylen = mpsignif(c->hostkey->n);
	ksmall = kbig = nil;
	if(serverkeylen+128 <= hostkeylen){
		ksmall = c->serverkey;
		kbig = c->hostkey;
	}else if(hostkeylen+128 <= serverkeylen){
		ksmall = c->hostkey;
		kbig = c->serverkey;
	}else
		error("server session and host keys do not differ by at least 128 bits");
	
	buflen = (mpsignif(kbig->n)+7)/8;
	buf = emalloc(buflen);

	debug(DBG_CRYPTO, "session key is %.*H\n", SESSKEYLEN, c->sesskey);
	memmove(buf, c->sesskey, SESSKEYLEN);
	for(i = 0; i < SESSIDLEN; i++)
		buf[i] ^= c->sessid[i];
	debug(DBG_CRYPTO, "munged session key is %.*H\n", SESSKEYLEN, buf);

	b = rsaencryptbuf(ksmall, buf, SESSKEYLEN);
	n = (mpsignif(ksmall->n)+7) / 8;
	mptoberjust(b, buf, n);
	mpfree(b);
	debug(DBG_CRYPTO, "encrypted with ksmall is %.*H\n", n, buf);

	b = rsaencryptbuf(kbig, buf, n);
	putmpint(m, b);
	debug(DBG_CRYPTO, "encrypted with kbig is %B\n", b);
	mpfree(b);

	memset(buf, 0, buflen);
	free(buf);

	putlong(m, c->flags);
	sendmsg(m);
}
예제 #4
0
파일: ecc.c 프로젝트: grobe0ba/plan9front
int
base58dec(char *src, uchar *dst, int len)
{
	mpint *n, *b, *r;
	char *t;
	int l;
	
	n = mpnew(0);
	r = mpnew(0);
	b = uitomp(58, nil);
	for(; *src; src++){
		t = strchr(code, *src);
		if(t == nil){
			mpfree(n);
			mpfree(r);
			mpfree(b);
			werrstr("invalid base58 char");
			return -1;
		}
		uitomp(t - code, r);
		mpmul(n, b, n);
		mpadd(n, r, n);
	}
	memset(dst, 0, len);
	l = (mpsignif(n) + 7) / 8;
	mptobe(n, dst + (len - l), l, nil);
	mpfree(n);
	mpfree(r);
	mpfree(b);
	return 0;
}
예제 #5
0
파일: rsa2pub.c 프로젝트: 00001/plan9port
void
main(int argc, char **argv)
{
	RSApriv *key;
	Attr *a;
	char *s;

	fmtinstall('A', _attrfmt);
	fmtinstall('B', mpfmt);
	quotefmtinstall();

	ARGBEGIN{
	default:
		usage();
	}ARGEND

	if(argc > 1)
		usage();

	if((key = getkey(argc, argv, 0, &a)) == nil)
		sysfatal("%r");

	s = smprint("key %A size=%d ek=%lB n=%lB\n",
		a, 
		mpsignif(key->pub.n), key->pub.ek, key->pub.n);
	if(s == nil)
		sysfatal("smprint: %r");
	write(1, s, strlen(s));
	exits(nil);
}
예제 #6
0
파일: pkcs1.c 프로젝트: zlxy/plan9
int
rsaverify(RSApub *key, DigestAlg *hash, uchar *digest, uint dlen,
          uchar *sig, uint siglen)
{
    uchar asn1[512], *buf;
    int n, len, pad;
    mpint *m, *mm, *s;

    /*
     * Create ASN.1
     */
    n = mkasn1(asn1, hash, digest, dlen);

    /*
     * Create number to sign.
     */
    len = (mpsignif(key->n)+7)/8 - 1;
    if(len < n+2) {
        werrstr("rsa key too short");
        return -1;
    }
    pad = len - (n+2);
    if(siglen < len) {
        werrstr("signature buffer too short");
        return -1;
    }
    buf = malloc(len);
    if(buf == nil)
        return -1;
    buf[0] = 0x01;
    memset(buf+1, 0xFF, pad);
    buf[1+pad] = 0x00;
    memmove(buf+1+pad+1, asn1, n);
    m = betomp(buf, len, nil);
    free(buf);
    if(m == nil)
        return -1;

    /*
     * Extract plaintext of signature.
     */
    s = betomp(sig, siglen, nil);
    if(s == nil)
        return -1;
    mm = rsaencrypt(key, s, nil);
    mpfree(s);
    if(mm == nil)
        return -1;
    if(mpcmp(m, mm) != 0) {
        werrstr("signature did not verify");
        mpfree(mm);
        mpfree(m);
        return -1;
    }
    mpfree(mm);
    mpfree(m);
    return 0;
}
예제 #7
0
파일: asn12rsa.c 프로젝트: npe9/harvey
void
main(int argc, char **argv)
{
    char *s;
    unsigned char *buf;
    int fd;
    int32_t n, tot;
    char *tag, *file;
    RSApriv *key;

    fmtinstall('B', mpfmt);

    tag = nil;
    ARGBEGIN{
    case 't':
        tag = EARGF(usage());
        break;
    default:
        usage();
    } ARGEND

    if(argc != 0 && argc != 1)
        usage();

    if(argc == 1)
        file = argv[0];
    else
        file = "#d/0";

    if((fd = open(file, OREAD)) < 0)
        sysfatal("open %s: %r", file);
    buf = nil;
    tot = 0;
    for(;;) {
        buf = realloc(buf, tot+8192);
        if(buf == nil)
            sysfatal("realloc: %r");
        if((n = read(fd, buf+tot, 8192)) < 0)
            sysfatal("read: %r");
        if(n == 0)
            break;
        tot += n;
    }

    key = asn1toRSApriv(buf, tot);
    if(key == nil)
        sysfatal("couldn't parse asn1 key");

    s = smprint("key proto=rsa %s%ssize=%d ek=%B !dk=%B n=%B !p=%B !q=%B !kp=%B !kq=%B !c2=%B\n",
                tag ? tag : "", tag ? " " : "",
                mpsignif(key->pub.n), key->pub.ek,
                key->dk, key->pub.n, key->p, key->q,
                key->kp, key->kq, key->c2);
    if(s == nil)
        sysfatal("smprint: %r");
    write(1, s, strlen(s));
    exits(0);
}
예제 #8
0
파일: ecc.c 프로젝트: grobe0ba/plan9front
int
ecdsaverify(ECdomain *dom, ECpub *pub, uchar *dig, int len, mpint *r, mpint *s)
{
	mpint *E, *t, *u1, *u2;
	ECpoint R, S;
	int ret;

	if(mpcmp(r, mpone) < 0 || mpcmp(s, mpone) < 0 || mpcmp(r, dom->n) >= 0 || mpcmp(r, dom->n) >= 0)
		return 0;
	E = betomp(dig, len, nil);
	if(mpsignif(dom->n) < 8*len)
		mpright(E, 8*len - mpsignif(dom->n), E);
	t = mpnew(0);
	u1 = mpnew(0);
	u2 = mpnew(0);
	R.x = mpnew(0);
	R.y = mpnew(0);
	S.x = mpnew(0);
	S.y = mpnew(0);
	mpinvert(s, dom->n, t);
	mpmul(E, t, u1);
	mpmod(u1, dom->n, u1);
	mpmul(r, t, u2);
	mpmod(u2, dom->n, u2);
	ecmul(dom, dom->G, u1, &R);
	ecmul(dom, pub, u2, &S);
	ecadd(dom, &R, &S, &R);
	ret = 0;
	if(!R.inf){
		mpmod(R.x, dom->n, t);
		ret = mpcmp(r, t) == 0;
	}
	mpfree(t);
	mpfree(u1);
	mpfree(u2);
	mpfree(R.x);
	mpfree(R.y);
	mpfree(S.x);
	mpfree(S.y);
	return ret;
}
예제 #9
0
파일: rsaalg.c 프로젝트: BGCX261/znos-git
/* generate an rsa secret key */
static void*
rsa_gen(int len)
{
	RSApriv *key;

	for(;;){
		key = rsagen(len, 6, 0);
		if(mpsignif(key->pub.n) == len)
			return key;
		rsaprivfree(key);
	}
}
예제 #10
0
파일: fold.c 프로젝트: aiju/hdl
static int
binput(Fmt *f, Const *c)
{
	mpint *n, *x;
	int rc, i, j, k;
	mpdigit p, q;

	n = mpcopy(c->n);
	x = mpcopy(c->x);
	j = mpsignif(n);
	k = mpsignif(x);
	i = j > k ? j : k;
	if(x->sign == -1){
		mptrunc(n, ++i, n);
		mptrunc(x, i, x);
	}else if(k >= j)
		i++;
	if(n->sign == -1)
		return fmtstrcpy(f, "(invalid)");
	if(i == 0)
		i = 1;
	j = (i + 31) / (sizeof(mpdigit) * 8);
	i = (i + sizeof(mpdigit) * 8 - 1) % (sizeof(mpdigit) * 8) + 1;
	rc = fmtstrcpy(f, "'b");
	while(--j >= 0){
		p = j >= n->top ? 0 : n->p[j];
		q = j >= x->top ? 0 : x->p[j];
		while(--i >= 0){
			k = (mpdigit)1<<i;
			rc += fmtstrcpy(f, (q & k) != 0 ?
				((p & k) != 0 ? "z" : "x") :
				((p & k) != 0 ? "1" : "0"));
		}
		i = sizeof(mpdigit) * 8;
	}
	mpfree(n);
	mpfree(x);
	return rc;
}
예제 #11
0
파일: pubkey.c 프로젝트: Earnestly/plan9
static int
parsepubkey(char *s, RSApub *key, char **sp, int base)
{
	int n;
	char *host, *p, *z;

	z = nil;
	n = strtoul(s, &p, 10);
	host = nil;
	if(n < Arbsz || !isspace(*p)){		/* maybe this is a host name */
		host = s;
		s = strpbrk(s, " \t");
		if(s == nil)
			return -1;
		z = s;
		*s++ = '\0';
		s += strspn(s, " \t");

		n = strtoul(s, &p, 10);
		if(n < Arbsz || !isspace(*p)){
			if(z)
				*z = ' ';
			return -1;
		}
	}

	/* Arbsz is just a sanity check */
	if((key->ek = strtomp(p, &p, base, nil)) == nil ||
	    (key->n = strtomp(p, &p, base, nil)) == nil ||
	    (*p != '\0' && !isspace(*p)) || mpsignif(key->n) < Arbsz) {
		mpfree(key->ek);
		mpfree(key->n);
		key->ek = nil;
		key->n = nil;
		if(z)
			*z = ' ';
		return -1;
	}
	if(host == nil){
		if(*p != '\0'){
			p += strspn(p, " \t");
			if(*p != '\0'){
				host = emalloc9p(strlen(p)+1);
				strcpy(host, p);
			}
		}
		free(s);
	}
	*sp = host;
	return 0;
}
예제 #12
0
파일: pkcs1.c 프로젝트: zlxy/plan9
int
rsasign(RSApriv *key, DigestAlg *hash, uchar *digest, uint dlen,
        uchar *sig, uint siglen)
{
    uchar asn1[64], *buf;
    int n, len, pad;
    mpint *m, *s;

    /*
     * Create ASN.1
     */
    n = mkasn1(asn1, hash, digest, dlen);

    /*
     * Create number to sign.
     */
    len = (mpsignif(key->pub.n)+7)/8 - 1;
    if(len < n+2) {
        werrstr("rsa key too short");
        return -1;
    }
    pad = len - (n+2);
    if(siglen < len) {
        werrstr("signature buffer too short");
        return -1;
    }
    buf = malloc(len);
    if(buf == nil)
        return -1;
    buf[0] = 0x01;
    memset(buf+1, 0xFF, pad);
    buf[1+pad] = 0x00;
    memmove(buf+1+pad+1, asn1, n);
    m = betomp(buf, len, nil);
    free(buf);
    if(m == nil)
        return -1;

    /*
     * Sign it.
     */
    s = rsadecrypt(key, m, nil);
    mpfree(m);
    if(s == nil)
        return -1;
    mptoberjust(s, sig, len+1);
    mpfree(s);
    return len+1;
}
예제 #13
0
파일: dsasign.c 프로젝트: npe9/harvey
DSAsig*
dsasign(DSApriv *priv, mpint *m)
{
	DSApub *pub = &priv->pub;
	DSAsig *sig;
	mpint *qm1, *k, *kinv, *r, *s;
	mpint *q = pub->q, *p = pub->p, *alpha = pub->alpha;
	int qlen = mpsignif(q);

	qm1 = mpnew(0);
	kinv = mpnew(0);
	r = mpnew(0);
	s = mpnew(0);
	k = mpnew(0);
	mpsub(pub->q, mpone, qm1);

	// find a k that has an inverse mod q
	while(1){
		mprand(qlen, genrandom, k);
		if((mpcmp(mpone, k) > 0) || (mpcmp(k, qm1) >= 0))
			continue;
		mpextendedgcd(k, q, r, kinv, s);
		if(mpcmp(r, mpone) != 0)
			continue;
		break;
	}

  	// make kinv positive
	mpmod(kinv, qm1, kinv);

	// r = ((alpha**k) mod p) mod q
	mpexp(alpha, k, p, r);
	mpmod(r, q, r);

	// s = (kinv*(m + ar)) mod q
	mpmul(r, priv->secret, s);
	mpadd(s, m, s);
	mpmul(s, kinv, s);
	mpmod(s, q, s);

	sig = dsasigalloc();
	sig->r = r;
	sig->s = s;
	mpfree(qm1);
	mpfree(k);
	mpfree(kinv);
	return sig;
}
예제 #14
0
void
main(int argc, char **argv)
{
	RSApriv *k;
	int ssh2;
	char *comment;

	fmtinstall('B', mpfmt);
	fmtinstall('[', encodefmt);

	ssh2 = 0;
	comment = "";

	ARGBEGIN{
	case 'c':
		comment = EARGF(usage());
		break;
	case '2':
		ssh2 = 1;
		break;
	default:
		usage();
	}ARGEND

	if(argc > 1)
		usage();

	if((k = getkey(argc, argv, 0, nil)) == nil)
		sysfatal("%r");

	if(ssh2) {
		uchar buf[8192], *p;

		p = buf;
		p = put4(p, 7);
		p = putn(p, "ssh-rsa", 7);
		p = putmp2(p, k->pub.ek);
		p = putmp2(p, k->pub.n);

		print("ssh-rsa %.*[ %s\n", (int)(p-buf), buf, comment);
	} else {
		print("%d %.10B %.10B %s\n", mpsignif(k->pub.n), k->pub.ek, k->pub.n, comment);
	}

	exits(nil);
}
예제 #15
0
파일: ecc.c 프로젝트: grobe0ba/plan9front
static mpint*
halfpt(ECdomain *dom, char *s, char **rptr, mpint *out)
{
	char *buf, *r;
	int n;
	mpint *ret;
	
	n = ((mpsignif(dom->p)+7)/8)*2;
	if(strlen(s) < n)
		return 0;
	buf = malloc(n+1);
	buf[n] = 0;
	memcpy(buf, s, n);
	ret = strtomp(buf, &r, 16, out);
	*rptr = s + (r - buf);
	free(buf);
	return ret;
}
예제 #16
0
파일: ecc.c 프로젝트: grobe0ba/plan9front
ECpriv*
ecgen(ECdomain *dom, ECpriv *p)
{
	if(p == nil){
		p = mallocz(sizeof(*p), 1);
		if(p == nil)
			return nil;
		p->x = mpnew(0);
		p->y = mpnew(0);
		p->d = mpnew(0);
	}
	for(;;){
		mprand(mpsignif(dom->n), genrandom, p->d);
		if(mpcmp(p->d, mpzero) > 0 && mpcmp(p->d, dom->n) < 0)
			break;
	}
	ecmul(dom, dom->G, p->d, p);
	return p;
}
예제 #17
0
파일: pubkey.c 프로젝트: 99years/plan9
int
appendkey(char *keyfile, char *host, RSApub *key)
{
	int fd;

	if((fd = open(keyfile, OWRITE)) < 0){
		fd = create(keyfile, OWRITE, 0666);
		if(fd < 0){
			fprint(2, "cannot open nor create %s: %r\n", keyfile);
			return -1;
		}
	}
	if(seek(fd, 0, 2) < 0
	|| fprint(fd, "%s %d %.10B %.10B\n", host, mpsignif(key->n), key->ek, key->n) < 0){
		close(fd);
		return -1;
	}
	close(fd);
	return 0;
}
예제 #18
0
파일: pubkey.c 프로젝트: Earnestly/plan9
int
appendkey(char *keyfile, char *host, RSApub *key)
{
	int fd, ret;

	ret = -1;
	if((fd = open(keyfile, OWRITE)) < 0){
		fd = create(keyfile, OWRITE, 0666);
		if(fd < 0){
			fprint(2, "%s: can't open nor create %s: %r\n",
				argv0, keyfile);
			return -1;
		}
	}
	if(seek(fd, 0, 2) >= 0 &&
	    fprint(fd, "%s %d %.10M %.10M\n", host, mpsignif(key->n),
	     key->ek, key->n) >= 0)
		ret = 0;
	close(fd);
	return ret;
}
예제 #19
0
파일: rsa2ssh.c 프로젝트: Requaos/harvey
void
main(int argc, char **argv)
{
	RSApriv *k;

	fmtinstall('B', mpfmt);

	ARGBEGIN{
	default:
		usage();
	}ARGEND

	if(argc > 1)
		usage();

	if((k = getkey(argc, argv, 0, nil)) == nil)
		sysfatal("%r");

	print("%d %.10B %.10B\n", mpsignif(k->pub.n), k->pub.ek, k->pub.n);
	exits(nil);
}
예제 #20
0
// Miller-Rabin probabilistic primality testing
//	Knuth (1981) Seminumerical Algorithms, p.379
//	Menezes et al () Handbook, p.39
// 0 if composite; 1 if almost surely prime, Pr(err)<1/4**nrep
int
probably_prime(mpint *n, int nrep)
{
	int j, k, rep, nbits, isprime = 1;
	mpint *nm1, *q, *x, *y, *r;

	if(n->sign < 0)
		sysfatal("negative prime candidate");

	if(nrep <= 0)
		nrep = 18;

	k = mptoi(n);
	if(k == 2)		// 2 is prime
		return 1;
	if(k < 2)		// 1 is not prime
		return 0;
	if((n->p[0] & 1) == 0)	// even is not prime
		return 0;

	// test against small prime numbers
	if(smallprimetest(n) < 0)
		return 0;

	// fermat test, 2^n mod n == 2 if p is prime
	x = uitomp(2, nil);
	y = mpnew(0);
	mpexp(x, n, n, y);
	k = mptoi(y);
	if(k != 2){
		mpfree(x);
		mpfree(y);
		return 0;
	}

	nbits = mpsignif(n);
	nm1 = mpnew(nbits);
	mpsub(n, mpone, nm1);	// nm1 = n - 1 */
	k = mplowbits0(nm1);
	q = mpnew(0);
	mpright(nm1, k, q);	// q = (n-1)/2**k

	for(rep = 0; rep < nrep; rep++){
		
		// x = random in [2, n-2]
		r = mprand(nbits, prng, nil);
		mpmod(r, nm1, x);
		mpfree(r);
		if(mpcmp(x, mpone) <= 0)
			continue;

		// y = x**q mod n
		mpexp(x, q, n, y);

		if(mpcmp(y, mpone) == 0 || mpcmp(y, nm1) == 0)
			goto done;

		for(j = 1; j < k; j++){
			mpmul(y, y, x);
			mpmod(x, n, y);	// y = y*y mod n
			if(mpcmp(y, nm1) == 0)
				goto done;
			if(mpcmp(y, mpone) == 0){
				isprime = 0;
				goto done;
			}
		}
		isprime = 0;
	}
done:
	mpfree(y);
	mpfree(x);
	mpfree(q);
	mpfree(nm1);
	return isprime;
}
예제 #21
0
/*
 * Miller-Rabin probabilistic primality testing
 *	Knuth (1981) Seminumerical Algorithms, p.379
 *	Menezes et al () Handbook, p.39
 * 0 if composite; 1 if almost surely prime, Pr(err)<1/4**nrep
 */
int
probably_prime(mpint *n, int nrep)
{
	int j, k, rep, nbits, isprime;
	mpint *nm1, *q, *x, *y, *r;

	if(n->sign < 0)
		sysfatal("negative prime candidate");

	if(nrep <= 0)
		nrep = 18;

	k = mptoi(n);
	if(k == 2)		/* 2 is prime */
		return 1;
	if(k < 2)		/* 1 is not prime */
		return 0;
	if((n->p[0] & 1) == 0)	/* even is not prime */
		return 0;

	/* test against small prime numbers */
	if(smallprimetest(n) < 0)
		return 0;

	/* fermat test, 2^n mod n == 2 if p is prime */
	x = uitomp(2, nil);
	y = mpnew(0);
	mpexp(x, n, n, y);
	k = mptoi(y);
	if(k != 2){
		mpfree(x);
		mpfree(y);
		return 0;
	}

	nbits = mpsignif(n);
	nm1 = mpnew(nbits);
	mpsub(n, mpone, nm1);	/* nm1 = n - 1 */
	k = mplowbits0(nm1);
	q = mpnew(0);
	mpright(nm1, k, q);	/* q = (n-1)/2**k */

	for(rep = 0; rep < nrep; rep++){
		for(;;){
			/* find x = random in [2, n-2] */
		 	r = mprand(nbits, prng, nil);
		 	mpmod(r, nm1, x);
		 	mpfree(r);
		 	if(mpcmp(x, mpone) > 0)
		 		break;
		}

		/* y = x**q mod n */
		mpexp(x, q, n, y);

		if(mpcmp(y, mpone) == 0 || mpcmp(y, nm1) == 0)
		 	continue;

		for(j = 1;; j++){
		 	if(j >= k) {
		 		isprime = 0;
		 		goto done;
		 	}
		 	mpmul(y, y, x);
		 	mpmod(x, n, y);	/* y = y*y mod n */
		 	if(mpcmp(y, nm1) == 0)
		 		break;
		 	if(mpcmp(y, mpone) == 0){
		 		isprime = 0;
		 		goto done;
		 	}
		}
	}
	isprime = 1;
done:
	mpfree(y);
	mpfree(x);
	mpfree(q);
	mpfree(nm1);
	return isprime;
}
예제 #22
0
파일: agent.c 프로젝트: bhanug/harvey
void
handlefullmsg(Conn *c, Achan *a)
{
	int i;
	uint32_t chan, len, n, rt;
	uint8_t type;
	Msg *m, mm;
	Msg *r;
	Key *k;
	int nk;
	mpint *mod, *ek, *chal;
	uint8_t sessid[16];
	uint8_t chalbuf[32];
	uint8_t digest[16];
	DigestState *s;
	static int first;

	assert(a->len == a->ndata);

	chan = a->chan;
	mm.rp = a->data;
	mm.ep = a->data+a->ndata;
	mm.c = c;
	m = &mm;

	type = getbyte(m);

	if(first == 0){
		first++;
		fmtinstall('H', encodefmt);
	}

	switch(type){
	default:
		debug(DBG_AUTH, "unknown msg type\n");
	Failure:
		debug(DBG_AUTH, "agent sending failure\n");
		r = allocmsg(m->c, SSH_MSG_CHANNEL_DATA, 13);
		putlong(r, chan);
		putlong(r, 5);
		putlong(r, 1);
		putbyte(r, SSH_AGENT_FAILURE);
		sendmsg(r);
		return;

	case SSH_AGENTC_REQUEST_RSA_IDENTITIES:
		debug(DBG_AUTH, "agent request identities\n");
		nk = listkeys(&k);
		if(nk < 0)
			goto Failure;
		len = 1+4;	/* type, nk */
		for(i=0; i<nk; i++){
			len += 4;
			len += 2+(mpsignif(k[i].ek)+7)/8;
			len += 2+(mpsignif(k[i].mod)+7)/8;
			len += 4+strlen(k[i].comment);
		}
		r = allocmsg(m->c, SSH_MSG_CHANNEL_DATA, 12+len);
		putlong(r, chan);
		putlong(r, len+4);
		putlong(r, len);
		putbyte(r, SSH_AGENT_RSA_IDENTITIES_ANSWER);
		putlong(r, nk);
		for(i=0; i<nk; i++){
			debug(DBG_AUTH, "\t%B %B %s\n", k[i].ek, k[i].mod, k[i].comment);
			putlong(r, mpsignif(k[i].mod));
			putmpint(r, k[i].ek);
			putmpint(r, k[i].mod);
			putstring(r, k[i].comment);
			mpfree(k[i].ek);
			mpfree(k[i].mod);
			free(k[i].comment);
		}
		free(k);
		sendmsg(r);
		break;

	case SSH_AGENTC_RSA_CHALLENGE:
		n = getlong(m);
		USED(n);	/* number of bits in key; who cares? */
		ek = getmpint(m);
		mod = getmpint(m);
		chal = getmpint(m);
		memmove(sessid, getbytes(m, 16), 16);
		rt = getlong(m);
		debug(DBG_AUTH, "agent challenge %B %B %B %ud (%p %p)\n",
			ek, mod, chal, rt, m->rp, m->ep);
		if(rt != 1 || dorsa(mod, ek, chal, chalbuf) < 0){
			mpfree(ek);
			mpfree(mod);
			mpfree(chal);
			goto Failure;
		}
		s = md5(chalbuf, 32, nil, nil);
		md5(sessid, 16, digest, s);
		r = allocmsg(m->c, SSH_MSG_CHANNEL_DATA, 12+1+16);
		putlong(r, chan);
		putlong(r, 4+16+1);
		putlong(r, 16+1);
		putbyte(r, SSH_AGENT_RSA_RESPONSE);
		putbytes(r, digest, 16);
		debug(DBG_AUTH, "digest %.16H\n", digest);
		sendmsg(r);
		mpfree(ek);
		mpfree(mod);
		mpfree(chal);
		return;

	case SSH_AGENTC_ADD_RSA_IDENTITY:
		goto Failure;
/*
		n = getlong(m);
		pubmod = getmpint(m);
		pubexp = getmpint(m);
		privexp = getmpint(m);
		pinversemodq = getmpint(m);
		p = getmpint(m);
		q = getmpint(m);
		comment = getstring(m);
		add to factotum;
		send SSH_AGENT_SUCCESS or SSH_AGENT_FAILURE;
*/

	case SSH_AGENTC_REMOVE_RSA_IDENTITY:
		goto Failure;
/*
		n = getlong(m);
		pubmod = getmpint(m);
		pubexp = getmpint(m);
		tell factotum to del key
		send SSH_AGENT_SUCCESS or SSH_AGENT_FAILURE;
*/
	}
}
예제 #23
0
RSApriv*
getkey(int argc, char **argv, int needprivate, Attr **pa)
{
    char *file, *s, *p;
    int sz;
    RSApriv *key;
    Biobuf *b;
    int regen;
    Attr *a;

    if(argc == 0)
        file = "#d/0";
    else
        file = argv[0];

    key = mallocz(sizeof(RSApriv), 1);
    if(key == nil)
        return nil;

    if((b = Bopen(file, OREAD)) == nil) {
        werrstr("open %s: %r", file);
        return nil;
    }
    s = Brdstr(b, '\n', 1);
    if(s == nil) {
        werrstr("read %s: %r", file);
        return nil;
    }
    if(strncmp(s, "key ", 4) != 0) {
        werrstr("bad key format");
        return nil;
    }

    regen = 0;
    a = _parseattr(s+4);
    if(a == nil) {
        werrstr("empty key");
        return nil;
    }
    if((p = _strfindattr(a, "proto")) == nil) {
        werrstr("no proto");
        return nil;
    }
    if(strcmp(p, "rsa") != 0) {
        werrstr("proto not rsa");
        return nil;
    }
    if((p = _strfindattr(a, "ek")) == nil) {
        werrstr("no ek");
        return nil;
    }
    if((key->pub.ek = strtomp(p, &p, 16, nil)) == nil || *p != 0) {
        werrstr("bad ek");
        return nil;
    }
    if((p = _strfindattr(a, "n")) == nil) {
        werrstr("no n");
        return nil;
    }
    if((key->pub.n = strtomp(p, &p, 16, nil)) == nil || *p != 0) {
        werrstr("bad n");
        return nil;
    }
    if((p = _strfindattr(a, "size")) == nil)
        fprint(2, "warning: missing size; will add\n");
    else if((sz = strtol(p, &p, 10)) == 0 || *p != 0)
        fprint(2, "warning: bad size; will correct\n");
    else if(sz != mpsignif(key->pub.n))
        fprint(2, "warning: wrong size (got %d, expected %d); will correct\n",
               sz, mpsignif(key->pub.n));
    if(!needprivate)
        goto call;
    if((p = _strfindattr(a, "!dk")) == nil) {
        werrstr("no !dk");
        return nil;
    }
    if((key->dk = strtomp(p, &p, 16, nil)) == nil || *p != 0) {
        werrstr("bad !dk");
        return nil;
    }
    if((p = _strfindattr(a, "!p")) == nil) {
        werrstr("no !p");
        return nil;
    }
    if((key->p = strtomp(p, &p, 16, nil)) == nil || *p != 0) {
        werrstr("bad !p");
        return nil;
    }
    if((p = _strfindattr(a, "!q")) == nil) {
        werrstr("no !q");
        return nil;
    }
    if((key->q = strtomp(p, &p, 16, nil)) == nil || *p != 0) {
        werrstr("bad !q");
        return nil;
    }
    if((p = _strfindattr(a, "!kp")) == nil) {
        fprint(2, "warning: no !kp\n");
        regen = 1;
        goto regen;
    }
    if((key->kp = strtomp(p, &p, 16, nil)) == nil || *p != 0) {
        fprint(2, "warning: bad !kp\n");
        regen = 1;
        goto regen;
    }
    if((p = _strfindattr(a, "!kq")) == nil) {
        fprint(2, "warning: no !kq\n");
        regen = 1;
        goto regen;
    }
    if((key->kq = strtomp(p, &p, 16, nil)) == nil || *p != 0) {
        fprint(2, "warning: bad !kq\n");
        regen = 1;
        goto regen;
    }
    if((p = _strfindattr(a, "!c2")) == nil) {
        fprint(2, "warning: no !c2\n");
        regen = 1;
        goto regen;
    }
    if((key->c2 = strtomp(p, &p, 16, nil)) == nil || *p != 0) {
        fprint(2, "warning: bad !c2\n");
        regen = 1;
        goto regen;
    }
regen:
    if(regen) {
        RSApriv *k2;

        k2 = rsafill(key->pub.n, key->pub.ek, key->dk, key->p, key->q);
        if(k2 == nil) {
            werrstr("regenerating chinese-remainder parts failed: %r");
            return nil;
        }
        key = k2;
    }
call:
    a = _delattr(a, "ek");
    a = _delattr(a, "n");
    a = _delattr(a, "size");
    a = _delattr(a, "!dk");
    a = _delattr(a, "!p");
    a = _delattr(a, "!q");
    a = _delattr(a, "!c2");
    a = _delattr(a, "!kp");
    a = _delattr(a, "!kq");
    if(pa)
        *pa = a;
    return key;
}
예제 #24
0
파일: smsg.c 프로젝트: AustenConrad/plan-9
static void
recv_ssh_cmsg_session_key(Conn *c, AuthRpc *rpc)
{
	int i, id, n, serverkeylen, hostkeylen;
	mpint *a, *b;
	uchar *buf;
	Msg *m;
	RSApriv *ksmall, *kbig;

	m = recvmsg(c, SSH_CMSG_SESSION_KEY);
	id = getbyte(m);
	c->cipher = nil;
	for(i=0; i<c->nokcipher; i++)
		if(c->okcipher[i]->id == id)
			c->cipher = c->okcipher[i];
	if(c->cipher == nil)
		sysfatal("invalid cipher selected");

	if(memcmp(getbytes(m, COOKIELEN), c->cookie, COOKIELEN) != 0)
		sysfatal("bad cookie");

	serverkeylen = mpsignif(c->serverkey->n);
	hostkeylen = mpsignif(c->hostkey->n);
	ksmall = kbig = nil;
	if(serverkeylen+128 <= hostkeylen){
		ksmall = c->serverpriv;
		kbig = nil;
	}else if(hostkeylen+128 <= serverkeylen){
		ksmall = nil;
		kbig = c->serverpriv;
	}else
		sysfatal("server session and host keys do not differ by at least 128 bits");

	b = getmpint(m);

	debug(DBG_CRYPTO, "encrypted with kbig is %B\n", b);
	if(kbig){
		a = rsadecrypt(kbig, b, nil);
		mpfree(b);
		b = a;
	}else
		b = rpcdecrypt(rpc, b);
	a = rsaunpad(b);
	mpfree(b);
	b = a;

	debug(DBG_CRYPTO, "encrypted with ksmall is %B\n", b);
	if(ksmall){
		a = rsadecrypt(ksmall, b, nil);
		mpfree(b);
		b = a;
	}else
		b = rpcdecrypt(rpc, b);
	a = rsaunpad(b);
	mpfree(b);
	b = a;

	debug(DBG_CRYPTO, "munged is %B\n", b);

	n = (mpsignif(b)+7)/8;
	if(n > SESSKEYLEN)
		sysfatal("client sent short session key");

	buf = emalloc(SESSKEYLEN);
	mptoberjust(b, buf, SESSKEYLEN);
	mpfree(b);

	for(i=0; i<SESSIDLEN; i++)
		buf[i] ^= c->sessid[i];

	memmove(c->sesskey, buf, SESSKEYLEN);

	debug(DBG_CRYPTO, "unmunged is %.*H\n", SESSKEYLEN, buf);

	c->flags = getlong(m);
	free(m);
}
예제 #25
0
파일: pubkey.c 프로젝트: Earnestly/plan9
int
replacekey(char *keyfile, char *host, RSApub *hostkey)
{
	int ret;
	char *h, *nkey, *p;
	Biobuf *br, *bw;
	Dir *d, nd;
	RSApub *k;

	ret = -1;
	d = nil;
	nkey = smprint("%s.new", keyfile);
	if(nkey == nil)
		return -1;

	if((br = Bopen(keyfile, OREAD)) == nil)
		goto out;
	if((bw = Bopen(nkey, OWRITE)) == nil){
		Bterm(br);
		goto out;
	}

	while((k = readpublickey(br, &h)) != nil){
		if(match(h, host) != 0)
			Bprint(bw, "%s %d %.10M %.10M\n",
				h, mpsignif(k->n), k->ek, k->n);
		free(h);
		rsapubfree(k);
	}
	Bprint(bw, "%s %d %.10M %.10M\n", host, mpsignif(hostkey->n),
		hostkey->ek, hostkey->n);
	Bterm(bw);
	Bterm(br);

	d = dirstat(nkey);
	if(d == nil){
		fprint(2, "new key file disappeared?\n");
		goto out;
	}

	p = strrchr(d->name, '.');
	if(p == nil || strcmp(p, ".new") != 0){
		fprint(2, "%s: new key file changed names? %s to %s\n",
			argv0, nkey, d->name);
		goto out;
	}

	*p = '\0';
	nulldir(&nd);
	nd.name = d->name;
	if(remove(keyfile) < 0){
		fprint(2, "%s: error removing %s: %r\n", argv0, keyfile);
		goto out;
	}
	if(dirwstat(nkey, &nd) < 0){
		fprint(2, "%s: error renaming %s to %s: %r\n",
			argv0, nkey, d->name);
		goto out;
	}
	ret = 0;
out:
	free(d);
	free(nkey);
	return ret;
}
예제 #26
0
파일: authrsa.c 프로젝트: aahud/harvey
static int
authrsafn(Conn *c)
{
	uint8_t chalbuf[32+SESSIDLEN], response[MD5dlen];
	char *s, *p;
	int afd, ret;
	AuthRpc *rpc;
	Msg *m;
	mpint *chal, *decr, *unpad, *mod;

	debug(DBG_AUTH, "rsa!\n");

	if((afd = open("/mnt/factotum/rpc", ORDWR)) < 0){
		debug(DBG_AUTH, "open /mnt/factotum/rpc: %r\n");
		return -1;
	}
	if((rpc = auth_allocrpc(afd)) == nil){
		debug(DBG_AUTH, "auth_allocrpc: %r\n");
		close(afd);
		return -1;
	}
	s = "proto=rsa role=client";
	if(auth_rpc(rpc, "start", s, strlen(s)) != ARok){
		debug(DBG_AUTH, "auth_rpc start %s failed: %r\n", s);
		auth_freerpc(rpc);
		close(afd);
		return -1;
	}

	ret = -1;
	debug(DBG_AUTH, "trying factotum rsa keys\n");
	while(auth_rpc(rpc, "read", nil, 0) == ARok){
		debug(DBG_AUTH, "try %s\n", (char*)rpc->arg);
		mod = strtomp(rpc->arg, nil, 16, nil);
		m = allocmsg(c, SSH_CMSG_AUTH_RSA, 16+(mpsignif(mod)+7/8));
		putmpint(m, mod);
		sendmsg(m);
		mpfree(mod);
		m = recvmsg(c, -1);
		switch(m->type){
		case SSH_SMSG_FAILURE:
			debug(DBG_AUTH, "\tnot accepted %s\n",
			      (char*)rpc->arg);
			free(m);
			continue;
		default:
			badmsg(m, 0);
		case SSH_SMSG_AUTH_RSA_CHALLENGE:
			break;
		}
		chal = getmpint(m);
		debug(DBG_AUTH, "\tgot challenge %B\n", chal);
		free(m);
		p = mptoa(chal, 16, nil, 0);
		mpfree(chal);
		if(p == nil){
			debug(DBG_AUTH, "\tmptoa failed: %r\n");
			unpad = mpnew(0);
			goto Keepgoing;
		}
		if(auth_rpc(rpc, "write", p, strlen(p)) != ARok){
			debug(DBG_AUTH, "\tauth_rpc write failed: %r\n");
			free(p);
			unpad = mpnew(0);	/* it will fail, we'll go round again */
			goto Keepgoing;
		}
		free(p);
		if(auth_rpc(rpc, "read", nil, 0) != ARok){
			debug(DBG_AUTH, "\tauth_rpc read failed: %r\n");
			unpad = mpnew(0);
			goto Keepgoing;
		}
		decr = strtomp(rpc->arg, nil, 16, nil);
		debug(DBG_AUTH, "\tdecrypted %B\n", decr);
		unpad = rsaunpad(decr);
		debug(DBG_AUTH, "\tunpadded %B\n", unpad);
		mpfree(decr);
	Keepgoing:
		mptoberjust(unpad, chalbuf, 32);
		mpfree(unpad);
		debug(DBG_AUTH, "\trjusted %.*H\n", 32, chalbuf);
		memmove(chalbuf+32, c->sessid, SESSIDLEN);
		debug(DBG_AUTH, "\tappend sesskey %.*H\n", 32, chalbuf);
		md5(chalbuf, 32+SESSIDLEN, response, nil);
		m = allocmsg(c, SSH_CMSG_AUTH_RSA_RESPONSE, MD5dlen);
		putbytes(m, response, MD5dlen);
		sendmsg(m);

		m = recvmsg(c, -1);
		switch(m->type){
		case SSH_SMSG_FAILURE:
			free(m);
			continue;
		default:
			badmsg(m, 0);
		case SSH_SMSG_SUCCESS:
			break;
		}
		ret = 0;
		break;
	}
	auth_freerpc(rpc);
	close(afd);
	return ret;
}
예제 #27
0
파일: rsagen.c 프로젝트: keedon/harvey
RSApriv*
rsagen(int nlen, int elen, int rounds)
{
	mpint *p, *q, *e, *d, *phi, *n, *t1, *t2, *kp, *kq, *c2;
	RSApriv *rsa;

	p = mpnew(nlen/2);
	q = mpnew(nlen/2);
	n = mpnew(nlen);
	e = mpnew(elen);
	d = mpnew(0);
	phi = mpnew(nlen);

	// create the prime factors and euclid's function
	genprime(p, nlen/2, rounds);
	genprime(q, nlen - mpsignif(p) + 1, rounds);
	mpmul(p, q, n);
	mpsub(p, mpone, e);
	mpsub(q, mpone, d);
	mpmul(e, d, phi);

	// find an e relatively prime to phi
	t1 = mpnew(0);
	t2 = mpnew(0);
	mprand(elen, genrandom, e);
	if(mpcmp(e,mptwo) <= 0)
		itomp(3, e);
	// See Menezes et al. p.291 "8.8 Note (selecting primes)" for discussion
	// of the merits of various choices of primes and exponents.  e=3 is a
	// common and recommended exponent, but doesn't necessarily work here
	// because we chose strong rather than safe primes.
	for(;;){
		mpextendedgcd(e, phi, t1, d, t2);
		if(mpcmp(t1, mpone) == 0)
			break;
		mpadd(mpone, e, e);
	}
	mpfree(t1);
	mpfree(t2);

	// compute chinese remainder coefficient
	c2 = mpnew(0);
	mpinvert(p, q, c2);

	// for crt a**k mod p == (a**(k mod p-1)) mod p
	kq = mpnew(0);
	kp = mpnew(0);
	mpsub(p, mpone, phi);
	mpmod(d, phi, kp);
	mpsub(q, mpone, phi);
	mpmod(d, phi, kq);

	rsa = rsaprivalloc();
	rsa->pub.ek = e;
	rsa->pub.n = n;
	rsa->dk = d;
	rsa->kp = kp;
	rsa->kq = kq;
	rsa->p = p;
	rsa->q = q;
	rsa->c2 = c2;

	mpfree(phi);

	return rsa;
}
예제 #28
0
파일: ecc.c 프로젝트: grobe0ba/plan9front
static int
mpsqrt(mpint *n, mpint *p, mpint *r)
{
	mpint *a, *t, *s, *xp, *xq, *yp, *yq, *zp, *zq, *N;

	if(mpleg(n, p) == -1)
		return 0;
	a = mpnew(0);
	t = mpnew(0);
	s = mpnew(0);
	N = mpnew(0);
	xp = mpnew(0);
	xq = mpnew(0);
	yp = mpnew(0);
	yq = mpnew(0);
	zp = mpnew(0);
	zq = mpnew(0);
	for(;;){
		for(;;){
			mprand(mpsignif(p), genrandom, a);
			if(mpcmp(a, mpzero) > 0 && mpcmp(a, p) < 0)
				break;
		}
		mpmul(a, a, t);
		mpsub(t, n, t);
		mpmod(t, p, t);
		if(mpleg(t, p) == -1)
			break;
	}
	mpadd(p, mpone, N);
	mpright(N, 1, N);
	mpmul(a, a, t);
	mpsub(t, n, t);
	mpassign(a, xp);
	uitomp(1, xq);
	uitomp(1, yp);
	uitomp(0, yq);
	while(mpcmp(N, mpzero) != 0){
		if(N->p[0] & 1){
			mpmul(xp, yp, zp);
			mpmul(xq, yq, zq);
			mpmul(zq, t, zq);
			mpadd(zp, zq, zp);
			mpmod(zp, p, zp);
			mpmul(xp, yq, zq);
			mpmul(xq, yp, s);
			mpadd(zq, s, zq);
			mpmod(zq, p, yq);
			mpassign(zp, yp);
		}
		mpmul(xp, xp, zp);
		mpmul(xq, xq, zq);
		mpmul(zq, t, zq);
		mpadd(zp, zq, zp);
		mpmod(zp, p, zp);
		mpmul(xp, xq, zq);
		mpadd(zq, zq, zq);
		mpmod(zq, p, xq);
		mpassign(zp, xp);
		mpright(N, 1, N);
	}
	if(mpcmp(yq, mpzero) != 0)
		abort();
	mpassign(yp, r);
	mpfree(a);
	mpfree(t);
	mpfree(s);
	mpfree(N);
	mpfree(xp);
	mpfree(xq);
	mpfree(yp);
	mpfree(yq);
	mpfree(zp);
	mpfree(zq);
	return 1;
}