Esempio n. 1
0
void
main(void)
{
	mpint *z = mpnew(0);
	mpint *p = mpnew(0);
	mpint *q = mpnew(0);
	mpint *nine = mpnew(0);

	fmtinstall('B', mpconv);
	strtomp("2492491", nil, 16, z);	// 38347921 = x*y = (2**28-9)/7,
				//    an example of 3**(n-1)=1 mod n
	strtomp("15662C00E811", nil, 16, p);// 23528569104401, a prime
	uitomp(9, nine);

	if(probably_prime(z, 5) == 1)
		fprint(2, "tricked primality test\n");
	if(probably_prime(nine, 5) == 1)
		fprint(2, "9 passed primality test!\n");
	if(probably_prime(p, 25) == 1)
		fprint(2, "ok\n");

	DSAprimes(q, p, nil);
	print("q=%B\np=%B\n", q, p);

	exits(0);
}
Esempio n. 2
0
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;
}
Esempio n. 3
0
static int
listkeys(Key **kp)
{
	Biobuf *b;
	Key *k;
	int nk;
	char *p, *f[20];
	int nf;
	mpint *mod, *ek;
	
	*kp = nil;
	if((b = Bopen("/mnt/factotum/ctl", OREAD)) == nil)
		return -1;
	
	k = nil;
	nk = 0;
	while((p = Brdline(b, '\n')) != nil){
		p[Blinelen(b)-1] = '\0';
		nf = tokenize(p, f, nelem(f));
		if(nf == 0 || strcmp(f[0], "key") != 0)
			continue;
		p = find(f, nf, "proto");
		if(p == nil || strcmp(p, "rsa") != 0)
			continue;
		p = find(f, nf, "n");
		if(p == nil || (mod = strtomp(p, nil, 16, nil)) == nil)
			continue;
		p = find(f, nf, "ek");
		if(p == nil || (ek = strtomp(p, nil, 16, nil)) == nil){
			mpfree(mod);
			continue;
		}
		p = find(f, nf, "comment");
		if(p == nil)
			p = "";
		k = erealloc(k, (nk+1)*sizeof(k[0]));
		k[nk].mod = mod;
		k[nk].ek = ek;
		k[nk].comment = emalloc(strlen(p)+1);
		strcpy(k[nk].comment, p);
		nk++;
	}
	Bterm(b);
	*kp = k;
	return nk;	
}
Esempio n. 4
0
static mpint*
rpcdecrypt(AuthRpc *rpc, mpint *b)
{
	mpint *a;
	char *p;

	p = mptoa(b, 16, nil, 0);
	if(auth_rpc(rpc, "write", p, strlen(p)) != ARok)
		sysfatal("factotum rsa write: %r");
	free(p);
	if(auth_rpc(rpc, "read", nil, 0) != ARok)
		sysfatal("factotum rsa read: %r");
	a = strtomp(rpc->arg, nil, 16, nil);
	mpfree(b);
	return a;
}
Esempio n. 5
0
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;
}
Esempio n. 6
0
void
testshift(char *str)
{
    mpint *b1, *b2;
    int i;

    b1 = strtomp(str, nil, 16, nil);
    malloccheck();
    fprint(2, "A");
    b2 = mpnew(0);
    fprint(2, "B");
    malloccheck();
    mpleft(b1, 20, b2);
    fprint(2, "C");
    malloccheck();
    mpfree(b1);
    fprint(2, "D");
    malloccheck();
    mpfree(b2);
}
Esempio n. 7
0
File: fold.c Progetto: aiju/hdl
void
consparse(Const *c, char *s)
{
	char t0[512], t1[512];
	char yc;
	char *p;
	int i, sz, b;

	memset(c, 0, sizeof(Const));
	if(strchr(s, '\'') == nil){
		c->n = strtomp(s, &p, 10, nil);
		if(c->n == nil) c->n = mpnew(0);
		c->x = mpnew(0);
		c->sign = 1;
		if(*p != 0){
		snope:
			b = 0;
			i = p - s;
			goto nope;
		}
		return;
	}
	if(*s != '\''){
		sz = strtol(s, &p, 10);
		if(*p != '\'')
			goto snope;
		s = p;
	}else
		sz = 0;
	s++;
	if(*s == 's' || *s == 'S'){
		c->sign = 1;
		s++;
	}
	switch(*s){
	case 'h': case 'H': b = 16; break;
	case 'd': case 'D': b = 10; break;
	case 'o': case 'O': b = 8; break;
	case 'b': case 'B': b = 2; break;
	default:
		error(nil, "'%c' invalid base specifier", *s);
		goto out;
	}
	c->base = b;
	s++;
	if(s[1] == 0 && (s[0] == 'x' || s[0] == 'X' || s[0] == 'z' || s[0] == 'Z' || s[0] == '?'))
		b = 2;
	switch(b){
	default: yc = '1'; break;
	case 8: yc = '7'; break;
	case 16: yc = 'f'; break;
	}
	for(i = 0; s[i] != 0; i++){
		if(s[i] == 'x' || s[i] == 'X'){
			t0[i] = '0';
			t1[i] = yc;
			if(b == 10)
				goto nope;
		}else if(s[i] == 'z' || s[i] == 'Z' || s[i] == '?'){
			t0[i] = yc;
			t1[i] = yc;
			if(b == 10)
				goto nope;
		}else{
			switch(b){
			case 2: if(s[i] > '1') goto nope; break;
			case 8: if(s[i] > '7') goto nope; break;
			case 10: if(s[i] > '9') goto nope; break;
			case 16: if(!isxdigit(s[i])) goto nope; break;
			}
			t0[i] = s[i];
			t1[i] = '0';
		}
	}
	t0[i] = 0;
	t1[i] = 0;
	switch(b){
	default: c->sz = i; break;
	case 8: c->sz = i * 3; break;
	case 16: c->sz = i * 4; break;
	}
	c->n = strtomp(t0, nil, b, nil);
	c->x = strtomp(t1, nil, b, nil);
	if(s[0] == 'x' || s[0] == 'X' || s[0] == 'z' || s[0] == 'Z' || s[0] == '?'){
		mpxtend(c->n, c->sz, c->n);
		mpxtend(c->x, c->sz, c->x);
	}
	if(c->n == nil) c->n = mpnew(0);
	if(c->x == nil) c->x = mpnew(0);
	if(sz != 0)
		if((b & 1) != 0){
			mpxtend(c->n, sz, c->n);
			mpxtend(c->x, sz, c->x);
		}else{
			mptrunc(c->n, sz, c->n);
			mptrunc(c->x, sz, c->x);
		}
	c->sz = sz;
	return;
nope:
	error(nil, "'%c' in %s number", s[i], b == 8 ? "octal": b == 16 ? "hexadecimal" : b == 2 ? "binary" : "decimal");
out:
	c->n = mpnew(0);
	c->x = mpnew(0);
	c->sz = 0;
}
Esempio n. 8
0
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;
}
Esempio n. 9
0
static int
dologin(int fd, char *S, int forceSTA)
{
	int i, n, rv;
	char *file, *mess, *nl;
	char msg[Maxmsg+1];
	PW *pw;
	SConn *conn;

	pw = nil;
	rv = -1;

	/* collect the first message */
	if((conn = newSConn(fd)) == nil)
		return -1;
	if(readstr(conn, msg) < 0){
		fprint(2, "secstored: remote: %s: %r\n", msg);
		writerr(conn, "can't read your first message");
		goto Out;
	}

	/* authenticate */
	if(PAKserver(conn, S, msg, &pw) < 0){
		if(pw != nil)
			syslog(0, LOG, "secstore denied for %s", pw->id);
		goto Out;
	}
	if((forceSTA || pw->status&STA) != 0){
		conn->write(conn, (uchar*)"STA", 3);
		if(readstr(conn, msg) < 10 || strncmp(msg, "STA", 3) != 0){
			syslog(0, LOG, "no STA from %s", pw->id);
			goto Out;
		}
		mess = secureidcheck(pw->id, msg+3);
		if(mess != nil){
			syslog(0, LOG, "secureidcheck denied %s because %s", pw->id, mess);
			goto Out;
		}
	}
	conn->write(conn, (uchar*)"OK", 2);
	syslog(0, LOG, "AUTH %s", pw->id);

	/* perform operations as asked */
	while((n = readstr(conn, msg)) > 0){
		if(nl = strchr(msg, '\n'))
			*nl = 0;
		syslog(0, LOG, "[%s] %s", pw->id, msg);

		if(strncmp(msg, "GET ", 4) == 0){
			file = validatefile(msg+4);
			if(file==nil || getfile(conn, pw->id, file) < 0)
				goto Err;

		}else if(strncmp(msg, "PUT ", 4) == 0){
			file = validatefile(msg+4);
			if(file==nil || putfile(conn, pw->id, file) < 0){
				syslog(0, LOG, "failed PUT %s/%s", pw->id, file);
				goto Err;
			}

		}else if(strncmp(msg, "RM ", 3) == 0){
			file = validatefile(msg+3);
			if(file==nil || removefile(conn, pw->id, file) < 0){
				syslog(0, LOG, "failed RM %s/%s", pw->id, file);
				goto Err;
			}

		}else if(strncmp(msg, "CHPASS", 6) == 0){
			if(readstr(conn, msg) < 0){
				syslog(0, LOG, "protocol botch CHPASS for %s", pw->id);
				writerr(conn, "protocol botch while setting PAK");
				goto Out;
			}
			pw->Hi = strtomp(msg, nil, 64, pw->Hi);
			for(i=0; i < 4 && putPW(pw) < 0; i++)
				syslog(0, LOG, "password change failed for %s (%d): %r", pw->id, i);
			if(i==4)
				goto Out;

		}else if(strncmp(msg, "BYE", 3) == 0){
			rv = 0;
			break;

		}else{
			writerr(conn, "unrecognized operation");
			break;
		}

	}
	if(n <= 0)
		syslog(0, LOG, "%s closed connection without saying goodbye", pw->id);

Out:
	freePW(pw);
	conn->free(conn);
	return rv;
Err:
	writerr(conn, "operation failed");
	goto Out;
}
Esempio n. 10
0
void
sshserverhandshake(Conn *c)
{
	char *p, buf[128];
	Biobuf *b;
	Attr *a;
	int i, afd;
	mpint *m;
	AuthRpc *rpc;
	RSApub *key;

	/*
	 * BUG: should use `attr' to get the key attributes
	 * after the read, but that's not implemented yet.
	 */
	if((b = Bopen("/mnt/factotum/ctl", OREAD)) == nil)
		sysfatal("open /mnt/factotum/ctl: %r");
	while((p = Brdline(b, '\n')) != nil){
		p[Blinelen(b)-1] = '\0';
		if(strstr(p, " proto=rsa ") && strstr(p, " service=sshserve "))
			break;
	}
	if(p == nil)
		sysfatal("no sshserve keys found in /mnt/factotum/ctl");
	a = _parseattr(p);
	Bterm(b);
	key = emalloc(sizeof(*key));
	if((p = _strfindattr(a, "n")) == nil)
		sysfatal("no n in sshserve key");
	if((key->n = strtomp(p, &p, 16, nil)) == nil || *p != 0)
		sysfatal("bad n in sshserve key");
	if((p = _strfindattr(a, "ek")) == nil)
		sysfatal("no ek in sshserve key");
	if((key->ek = strtomp(p, &p, 16, nil)) == nil || *p != 0)
		sysfatal("bad ek in sshserve key");
	_freeattr(a);

	if((afd = open("/mnt/factotum/rpc", ORDWR)) < 0)
		sysfatal("open /mnt/factotum/rpc: %r");
	if((rpc = auth_allocrpc(afd)) == nil)
		sysfatal("auth_allocrpc: %r");
	p = "proto=rsa role=client service=sshserve";
	if(auth_rpc(rpc, "start", p, strlen(p)) != ARok)
		sysfatal("auth_rpc start %s: %r", p);
	if(auth_rpc(rpc, "read", nil, 0) != ARok)
		sysfatal("auth_rpc read: %r");
	m = strtomp(rpc->arg, nil, 16, nil);
	if(mpcmp(m, key->n) != 0)
		sysfatal("key in /mnt/factotum/ctl does not match rpc key");
	mpfree(m);
	c->hostkey = key;

	/* send id string */
	fprint(c->fd[0], "SSH-1.5-Plan9\n");

	/* receive id string */
	if(readstrnl(c->fd[0], buf, sizeof buf) < 0)
		sysfatal("reading server version: %r");

	/* id string is "SSH-m.n-comment".  We need m=1, n>=5. */
	if(strncmp(buf, "SSH-", 4) != 0
	|| strtol(buf+4, &p, 10) != 1
	|| *p != '.'
	|| strtol(p+1, &p, 10) < 5
	|| *p != '-')
		sysfatal("protocol mismatch; got %s, need SSH-1.x for x>=5", buf);

	for(i=0; i<COOKIELEN; i++)
		c->cookie[i] = fastrand();
	calcsessid(c);
	send_ssh_smsg_public_key(c);
	recv_ssh_cmsg_session_key(c, rpc);
	auth_freerpc(rpc);
	close(afd);

	c->cstate = (*c->cipher->init)(c, 1);		/* turns on encryption */
	sendmsg(allocmsg(c, SSH_SMSG_SUCCESS, 0));

	authsrvuser(c);
}
Esempio n. 11
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;
}
Esempio n. 12
0
DSApriv*
getdsakey(int argc, char **argv, int needprivate, Attr **pa)
{
    char *file, *s, *p;
    DSApriv *key;
    Biobuf *b;
    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;
    }

    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, "dsa") != 0) {
        werrstr("proto not dsa");
        return nil;
    }
    if((p = _strfindattr(a, "p")) == nil) {
        werrstr("no p");
        return nil;
    }
    if((key->pub.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->pub.q = strtomp(p, &p, 16, nil)) == nil || *p != 0) {
        werrstr("bad q");
        return nil;
    }
    if((p = _strfindattr(a, "alpha")) == nil) {
        werrstr("no alpha");
        return nil;
    }
    if((key->pub.alpha = strtomp(p, &p, 16, nil)) == nil || *p != 0) {
        werrstr("bad alpha");
        return nil;
    }
    if((p = _strfindattr(a, "key")) == nil) {
        werrstr("no key=");
        return nil;
    }
    if((key->pub.key = strtomp(p, &p, 16, nil)) == nil || *p != 0) {
        werrstr("bad key=");
        return nil;
    }
    if(!needprivate)
        goto call;
    if((p = _strfindattr(a, "!secret")) == nil) {
        werrstr("no !secret");
        return nil;
    }
    if((key->secret = strtomp(p, &p, 16, nil)) == nil || *p != 0) {
        werrstr("bad !secret");
        return nil;
    }
call:
    a = _delattr(a, "p");
    a = _delattr(a, "q");
    a = _delattr(a, "alpha");
    a = _delattr(a, "key");
    a = _delattr(a, "!secret");
    if(pa)
        *pa = a;
    return key;
}
Esempio n. 13
0
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;
}
Esempio n. 14
0
PW *
getPW(char *id, int dead_or_alive)
{
	ulong now = time(0);
	char *f1, *f2, *oid;		/* fields 1, 2 = attribute, value */
	Biobuf *bin;
	PW *pw;

	oid = id;
	if((bin = openPW(id, OREAD)) == 0){
		id = "FICTITIOUS";
		if((bin = openPW(id, OREAD)) == 0){
			werrstr("accounts %s and FICTITIOUS do not exist", oid);
			return nil;
		}
	}
	pw = emalloc(sizeof *pw);
	pw->id = estrdup(id);
	pw->status |= Enabled;
	while( (f1 = Brdline(bin, '\n')) != 0){
		f1[Blinelen(bin)-1] = 0;
		for(f2 = f1; *f2 && *f2 != ' ' && *f2 != '\t'; f2++)
			;
		if(*f2)
			for(*f2++ = 0; *f2 && (*f2==' ' || *f2=='\t'); f2++)
				;
		if(strcmp(f1, "exp") == 0)
			pw->expire = strtoul(f2, 0, 10);
		else if(strcmp(f1, "DISABLED") == 0)
			pw->status &= ~Enabled;
		else if(strcmp(f1, "STA") == 0)
			pw->status |= STA;
		else if(strcmp(f1, "failed") == 0)
			pw->failed = strtoul(f2, 0, 10);
		else if(strcmp(f1, "other") == 0)
			pw->other = estrdup(f2);
		else if(strcmp(f1, "PAK-Hi") == 0)
			pw->Hi = strtomp(f2, nil, 64, nil);
	}
	Bterm(bin);
	if(pw->Hi == nil){
		werrstr("corrupted account file for %s", pw->id);
		freePW(pw);
		return nil;
	}
	if(dead_or_alive)
		return pw;  /* return for editing, whether valid now or not */
	if(pw->expire != 0 && pw->expire <= now){
		/* %.28s excludes ctime's newline */
		werrstr("account %s expired at %.28s", pw->id,
			ctime(pw->expire));
		freePW(pw);
		return nil;
	}
	if((pw->status & Enabled) == 0){
		werrstr("account %s disabled", pw->id);
		freePW(pw);
		return nil;
	}
	if(pw->failed < 10)
		return pw;	/* success */
	if(now < mtimePW(id)+300){
		werrstr("too many failures; try again in five minutes");
		freePW(pw);
		return nil;
	}
	pw->failed = 0;
	putPW(pw);	/* reset failed-login-counter after five minutes */
	return pw;
}
Esempio n. 15
0
PW *
getPW(char *id, int dead_or_alive)
{
	uint now = time(0);
	Biobuf *bin;
	PW *pw;
	char *f1, *f2; /* fields 1, 2 = attribute, value */

	if((bin = openPW(id, OREAD)) == 0){
		id = "FICTITIOUS";
		if((bin = openPW(id, OREAD)) == 0){
			werrstr("account does not exist");
			return nil;
		}
	}
	pw = emalloc(sizeof(*pw));
	pw->id = estrdup(id);
	pw->status |= Enabled;
	while( (f1 = Brdline(bin, '\n')) != 0){
		f1[Blinelen(bin)-1] = 0;
		for(f2 = f1; *f2 && (*f2!=' ') && (*f2!='\t'); f2++){}
		if(*f2)
			for(*f2++ = 0; *f2 && (*f2==' ' || *f2=='\t'); f2++){}
		if(strcmp(f1, "exp") == 0){
			pw->expire = strtoul(f2, 0, 10);
		}else if(strcmp(f1, "DISABLED") == 0){
			pw->status &= ~Enabled;
		}else if(strcmp(f1, "STA") == 0){
			pw->status |= STA;
		}else if(strcmp(f1, "failed") == 0){
			pw->failed = strtoul(f2, 0, 10);
		}else if(strcmp(f1, "other") == 0){
			pw->other = estrdup(f2);
		}else if(strcmp(f1, "PAK-Hi") == 0){
			pw->Hi = strtomp(f2, nil, 64, nil);
		}
	}
	Bterm(bin);
	if(dead_or_alive)
		return pw;  /* return PW entry for editing, whether currently valid or not */
	if(pw->expire <= now){
		werrstr("account expired");
		freePW(pw);
		return nil;
	}
	if((pw->status & Enabled) == 0){
		werrstr("account disabled");
		freePW(pw);
		return nil;
	}
	if(pw->failed < 10)
		return pw;  /* success */
	if(now < mtimePW(id)+300){
		werrstr("too many failures; try again in five minutes");
		freePW(pw);
		return nil;
	}
	pw->failed = 0;
	putPW(pw);  /* reset failed-login-counter after five minutes */
	return pw;
}