示例#1
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);
}
示例#2
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;
}
示例#3
0
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);
}
示例#4
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;
}
示例#5
0
文件: agent.c 项目: bhanug/harvey
static int
dorsa(mpint *mod, mpint *exp, mpint *chal, uint8_t chalbuf[32])
{
	int afd;
	AuthRpc *rpc;
	mpint *m;
	char buf[4096], *p;
	mpint *decr, *unpad;

	USED(exp);

	snprint(buf, sizeof buf, "proto=rsa service=ssh role=client");
	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;
	}
	if(auth_rpc(rpc, "start", buf, strlen(buf)) != ARok){
		debug(DBG_AUTH, "auth_rpc start failed: %r\n");
	Die:
		auth_freerpc(rpc);
		close(afd);
		return -1;
	}
	m = nil;
	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);
		m = strtomp(rpc->arg, nil, 16, nil);
		if(mpcmp(m, mod) == 0)
			break;
		mpfree(m);
		m = nil;
	}
	if(m == nil)
		goto Die;
	mpfree(m);
	
	p = mptoa(chal, 16, nil, 0);
	if(p == nil){
		debug(DBG_AUTH, "\tmptoa failed: %r\n");
		goto Die;
	}
	if(auth_rpc(rpc, "write", p, strlen(p)) != ARok){
		debug(DBG_AUTH, "\tauth_rpc write failed: %r\n");
		free(p);
		goto Die;
	}
	free(p);
	if(auth_rpc(rpc, "read", nil, 0) != ARok){
		debug(DBG_AUTH, "\tauth_rpc read failed: %r\n");
		goto Die;
	}
	decr = strtomp(rpc->arg, nil, 16, nil);
	if(decr == nil){
		debug(DBG_AUTH, "\tdecr %s failed\n", rpc->arg);
		goto Die;
	}
	debug(DBG_AUTH, "\tdecrypted %B\n", decr);
	unpad = rsaunpad(decr);
	if(unpad == nil){
		debug(DBG_AUTH, "\tunpad %B failed\n", decr);
		mpfree(decr);
		goto Die;
	}
	debug(DBG_AUTH, "\tunpadded %B\n", unpad);
	mpfree(decr);
	mptoberjust(unpad, chalbuf, 32);
	mpfree(unpad);
	auth_freerpc(rpc);
	close(afd);
	return 0;
}