int tcp_session_uinit(session_t *psession) { pthread_mutex_lock(&psession->send_lock); if (psession->pdev) { event_del((struct event*)psession->pdev); mpfree(psession->pdev); psession->pdev = NULL; } pthread_mutex_unlock(&psession->send_lock); pthread_mutex_lock(&psession->recv_lock); if (psession->wtev) { event_del((struct event*)psession->wtev); mpfree(psession->wtev); psession->wtev = NULL; } pthread_mutex_unlock(&psession->recv_lock); cdnmsg_t* msg; while (!gdsl_list_is_empty(psession->send_queue)) { msg = (cdnmsg_t *) gdsl_list_remove_head(psession->send_queue); if (!msg) break; mpfree(msg); } if (psession->send_incomplete) { mpfree(psession->send_incomplete); psession->send_incomplete = NULL; } if (psession->recv_incomplete) { mpfree(psession->recv_incomplete); psession->recv_incomplete = NULL; } gdsl_list_free(psession->send_queue); gdsl_list_free(psession->recv_queue); pthread_mutex_destroy(&psession->send_lock); pthread_mutex_destroy(&psession->recv_lock); return 0; }
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; }
void rsaprivfree(RSApriv *rsa) { if(rsa == nil) return; mpfree(rsa->pub.ek); mpfree(rsa->pub.n); mpfree(rsa->dk); mpfree(rsa->p); mpfree(rsa->q); mpfree(rsa->kp); mpfree(rsa->kq); mpfree(rsa->c2); free(rsa); }
int ecverify(ECdomain *dom, ECpoint *a) { mpint *p, *q; int r; if(a->inf) return 1; p = mpnew(0); q = mpnew(0); mpmul(a->y, a->y, p); mpmod(p, dom->p, p); mpmul(a->x, a->x, q); mpadd(q, dom->a, q); mpmul(a->x, q, q); mpadd(q, dom->b, q); mpmod(q, dom->p, q); r = mpcmp(p, q); mpfree(p); mpfree(q); return r == 0; }
void tcp_session_write(int fd,void* arg) { int r; session_t *se = (session_t *) arg; struct event *ev = se->wtev; /* pthread_mutex_lock(&voolefs.objlock), se = (session_t *) gdsl_hash_search(voolefs.accesses, INT2PTR(fd)), pthread_mutex_unlock(&voolefs.objlock); */ if (!se || se->status == NS_DISUSE) { //cberror(ev, se); return 0; } if (se->status == NS_CONNECTING) { if (tcp_session_check(se)) { printf("i can't connect\n"); return 0; } } cdnmsg_t *msg = (cdnmsg_t *) se->send_incomplete; if (se->besent == 0) { /* to send a new message */ pthread_mutex_lock(&se->send_lock); msg = (cdnmsg_t *) gdsl_list_remove_head(se->send_queue); if (!msg) { event_del(ev); mpfree(ev); se->wtev = NULL; pthread_mutex_unlock(&se->send_lock); return ; } se->send_incomplete = (uint8_t *) msg; se->besent = ntohl(msg->head.len); pthread_mutex_unlock(&se->send_lock); } r = send(fd, ((uint8_t *)msg) +ntohl(msg->head.len) -se->besent, se->besent, MSG_NOSIGNAL); if (r == 0 || (r < 0 && errno != EAGAIN && errno != EINTR)) return ;//!cberror(ev, se); if (r == se->besent) { /* complete it */ se->send_incomplete = 0; se->besent = 0; } else if (r > 0) se->besent = se->besent -r; printf("i am send by fd %d - send %d\n",fd, r); }
static int mpleg(mpint *a, mpint *b) { int r, k; mpint *m, *n, *t; r = 1; m = mpcopy(a); n = mpcopy(b); for(;;){ if(mpcmp(m, n) > 0) mpmod(m, n, m); if(mpcmp(m, mpzero) == 0){ r = 0; break; } if(mpcmp(m, mpone) == 0) break; k = mplowbits0(m); if(k > 0){ if(k & 1) switch(n->p[0] & 15){ case 3: case 5: case 11: case 13: r = -r; } mpright(m, k, m); } if((n->p[0] & 3) == 3 && (m->p[0] & 3) == 3) r = -r; t = m; m = n; n = t; } mpfree(m); mpfree(n); return r; }
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; }
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; }
int voole_release(const char *path, struct fuse_file_info *finfo) { finfo_t *fi = (finfo_t*)finfo->fh; session_t* se; while (!gdsl_list_is_empty(fi->list_session)) { se = (session_t*)gdsl_list_remove_head(fi->list_session); if (!se) break; tcp_session_close(se); tcp_session_uinit(se); } gdsl_hash_flush(fi->hash_session); pthread_mutex_destroy(&fi->flock); mpfree(fi); finfo->fh = NULL; return 0; }
/* garners algorithm for converting residue form to linear */ void crtout(CRTpre *crt, CRTres *res, mpint *x) { mpint *u; int i; u = mpnew(0); mpassign(res->r[0], x); for(i = 1; i < crt->n; i++){ mpsub(res->r[i], x, u); mpmul(u, crt->c[i], u); mpmod(u, crt->m[i], u); mpmul(u, crt->p[i-1], u); mpadd(x, u, x); } mpfree(u); }
/* setup crt info, returns a newly created structure */ CRTpre* crtpre(int n, mpint **m) { CRTpre *crt; int i, j; mpint *u; crt = malloc(sizeof(CRTpre)+sizeof(mpint)*3*n); if(crt == nil) sysfatal("crtpre: %r"); crt->m = crt->a; crt->c = crt->a+n; crt->p = crt->c+n; crt->n = n; /* make a copy of the moduli */ for(i = 0; i < n; i++) crt->m[i] = mpcopy(m[i]); /* precompute the products */ u = mpcopy(mpone); for(i = 0; i < n; i++){ mpmul(u, m[i], u); crt->p[i] = mpcopy(u); } /* precompute the coefficients */ for(i = 1; i < n; i++){ crt->c[i] = mpcopy(mpone); for(j = 0; j < i; j++){ mpinvert(m[j], m[i], u); mpmul(u, crt->c[i], u); mpmod(u, m[i], crt->c[i]); } } mpfree(u); return crt; }
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; }
void mpmul(mpint *b1, mpint *b2, mpint *prod) { mpint *oprod; oprod = nil; if(prod == b1 || prod == b2){ oprod = prod; prod = mpnew(0); } prod->top = 0; mpbits(prod, (b1->top+b2->top+1)*Dbits); mpvecmul(b1->p, b1->top, b2->p, b2->top, prod->p); prod->top = b1->top+b2->top+1; prod->sign = b1->sign*b2->sign; mpnorm(prod); if(oprod != nil){ mpassign(prod, oprod); mpfree(prod); } }
int tcp_cin_init(session_t** se) { int rt=0; session_t* pcon = NULL; pcon =(session_t*) mpcalloc(sizeof(session_t)); if (!pcon) goto calloc_fail; pcon->host = voolefs.phost[0].host; pcon->port = voolefs.phost[0].port; rt = tcp_session_open(pcon); if (rt) goto open_fail; rt = tcp_session_init(pcon); if (rt) goto init_fail; *se = pcon; return rt; init_fail: close(pcon->fd); open_fail: mpfree(pcon); calloc_fail: *se = NULL; return rt; }
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; }
/* * 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; }
void ecadd(ECdomain *dom, ECpoint *a, ECpoint *b, ECpoint *s) { mpint *l, *k, *sx, *sy; if(a->inf && b->inf){ s->inf = 1; return; } if(a->inf){ ecassign(dom, b, s); return; } if(b->inf){ ecassign(dom, a, s); return; } if(mpcmp(a->x, b->x) == 0 && (mpcmp(a->y, mpzero) == 0 || mpcmp(a->y, b->y) != 0)){ s->inf = 1; return; } l = mpnew(0); k = mpnew(0); sx = mpnew(0); sy = mpnew(0); if(mpcmp(a->x, b->x) == 0 && mpcmp(a->y, b->y) == 0){ mpadd(mpone, mptwo, k); mpmul(a->x, a->x, l); mpmul(l, k, l); mpadd(l, dom->a, l); mpleft(a->y, 1, k); mpmod(k, dom->p, k); mpinvert(k, dom->p, k); mpmul(k, l, l); mpmod(l, dom->p, l); mpleft(a->x, 1, k); mpmul(l, l, sx); mpsub(sx, k, sx); mpmod(sx, dom->p, sx); mpsub(a->x, sx, sy); mpmul(l, sy, sy); mpsub(sy, a->y, sy); mpmod(sy, dom->p, sy); mpassign(sx, s->x); mpassign(sy, s->y); mpfree(sx); mpfree(sy); mpfree(l); mpfree(k); return; } mpsub(b->y, a->y, l); mpmod(l, dom->p, l); mpsub(b->x, a->x, k); mpmod(k, dom->p, k); mpinvert(k, dom->p, k); mpmul(k, l, l); mpmod(l, dom->p, l); mpmul(l, l, sx); mpsub(sx, a->x, sx); mpsub(sx, b->x, sx); mpmod(sx, dom->p, sx); mpsub(a->x, sx, sy); mpmul(sy, l, sy); mpsub(sy, a->y, sy); mpmod(sy, dom->p, sy); mpassign(sx, s->x); mpassign(sy, s->y); mpfree(sx); mpfree(sy); mpfree(l); mpfree(k); }
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; */ } }
int verifysigner(uchar *sign, int len, uchar *data, ulong ndata) { Get sig; int alg; ulong issued, expires, now; int footprint, r, n; uchar buf[128], digest[SHA1dlen]; DigestState *ds; volatile struct {mpint* b;} b; volatile struct {mpint* s;} s; SigAlgVec *sa; Signerkey *key; Skeyset *sigs; /* alg[1] issued[4] expires[4] footprint[2] signer[n] sig[m] */ sigs = up->env->sigs; if(sigs == nil) return 1; /* not enforcing signed modules */ sig.p = sign; sig.ep = sign+len; alg = vc(&sig); if(alg != 2) return 0; /* we do only SHA1/RSA */ sa = findsigalg("rsa"); if(sa == nil) return 0; if(vs(buf, sizeof(buf), &sig, 4) < 0) return 0; now = osusectime()/1000000; issued = G32(buf); if(vs(buf, sizeof(buf), &sig, 4) < 0) return 0; if(issued != 0 && now < issued) return 0; expires = G32(buf); if(expires != 0 && now >= expires) return 0; footprint = vc(&sig) << 8; footprint |= vc(&sig); if(footprint < 0) return 0; r = 0; b.b = nil; s.s = nil; qlock(&sigs->l); if(waserror()) goto out; if((n = vs(buf, sizeof(buf)-NUMSIZE-1, &sig, -1)) < 0) /* owner */ goto out; buf[n] = 0; key = findsignerkey(sigs, sa->name, footprint, (char*)buf); if(key == nil) goto out; n += snprint((char*)buf+n, NUMSIZE, " %lud", expires); ds = sha1(buf, n, nil, nil); sha1(data, ndata, digest, ds); b.b = betomp(digest, SHA1dlen, nil); if(b.b == nil) goto out; s.s = betomp(sig.p, sig.ep-sig.p, nil); if(s.s == nil) goto out; r = (*sa->verify)(b.b, s.s, key->pk); out: qunlock(&sigs->l); if(b.b != nil) mpfree(b.b); if(s.s != nil) mpfree(s.s); return r; }
/* * Read an ascii label in from FILE f, * in the same format as that put out by display(), * and fill in lp. */ int getasciilabel(FILE *f, struct disklabel *lp) { char **cpp, *cp; const char *errstr; struct partition *pp; char *mp, *tp, *s, line[BUFSIZ]; char **omountpoints = NULL; int lineno = 0, errors = 0; u_int32_t v, fsize; u_int64_t lv; unsigned int part; lp->d_version = 1; lp->d_bbsize = BBSIZE; /* XXX */ lp->d_sbsize = SBSIZE; /* XXX */ if (!(omountpoints = calloc(MAXPARTITIONS, sizeof(char *)))) errx(4, "out of memory"); mpcopy(omountpoints, mountpoints); for (part = 0; part < MAXPARTITIONS; part++) { free(mountpoints[part]); mountpoints[part] = NULL; } while (fgets(line, sizeof(line), f)) { lineno++; mp = NULL; if ((cp = strpbrk(line, "\r\n"))) *cp = '\0'; if ((cp = strpbrk(line, "#"))) { *cp = '\0'; mp = skip(cp+1); if (mp && *mp != '/') mp = NULL; } cp = skip(line); if (cp == NULL) continue; tp = strchr(cp, ':'); if (tp == NULL) { warnx("line %d: syntax error", lineno); errors++; continue; } *tp++ = '\0', tp = skip(tp); if (!strcmp(cp, "type")) { if (tp == NULL) tp = "unknown"; else if (strcasecmp(tp, "IDE") == 0) tp = "ESDI"; cpp = dktypenames; for (; cpp < &dktypenames[DKMAXTYPES]; cpp++) if ((s = *cpp) && !strcasecmp(s, tp)) { lp->d_type = cpp - dktypenames; goto next; } v = GETNUM(lp->d_type, tp, 0, &errstr); if (errstr || v >= DKMAXTYPES) warnx("line %d: warning, unknown disk type: %s", lineno, tp); lp->d_type = v; continue; } if (!strcmp(cp, "flags")) { for (v = 0; (cp = tp) && *cp != '\0';) { tp = word(cp); if (!strcmp(cp, "badsect")) v |= D_BADSECT; else if (!strcmp(cp, "vendor")) v |= D_VENDOR; else { warnx("line %d: bad flag: %s", lineno, cp); errors++; } } lp->d_flags = v; continue; } if (!strcmp(cp, "drivedata")) { int i; for (i = 0; (cp = tp) && *cp != '\0' && i < NDDATA;) { v = GETNUM(lp->d_drivedata[i], cp, 0, &errstr); if (errstr) warnx("line %d: bad drivedata %s", lineno, cp); lp->d_drivedata[i++] = v; tp = word(cp); } continue; } if (sscanf(cp, "%d partitions", &v) == 1) { if (v == 0 || v > MAXPARTITIONS) { warnx("line %d: bad # of partitions", lineno); lp->d_npartitions = MAXPARTITIONS; errors++; } else lp->d_npartitions = v; continue; } if (tp == NULL) tp = ""; if (!strcmp(cp, "disk")) { strncpy(lp->d_typename, tp, sizeof (lp->d_typename)); continue; } if (!strcmp(cp, "label")) { strncpy(lp->d_packname, tp, sizeof (lp->d_packname)); continue; } if (!strcmp(cp, "duid")) { if (duid_parse(lp, tp) != 0) { warnx("line %d: bad %s: %s", lineno, cp, tp); errors++; } continue; } if (!strcmp(cp, "bytes/sector")) { v = GETNUM(lp->d_secsize, tp, 1, &errstr); if (errstr || (v % 512) != 0) { warnx("line %d: bad %s: %s", lineno, cp, tp); errors++; } else lp->d_secsize = v; continue; } if (!strcmp(cp, "sectors/track")) { v = GETNUM(lp->d_nsectors, tp, 1, &errstr); if (errstr) { warnx("line %d: bad %s: %s", lineno, cp, tp); errors++; } else lp->d_nsectors = v; continue; } if (!strcmp(cp, "sectors/cylinder")) { v = GETNUM(lp->d_secpercyl, tp, 1, &errstr); if (errstr) { warnx("line %d: bad %s: %s", lineno, cp, tp); errors++; } else lp->d_secpercyl = v; continue; } if (!strcmp(cp, "tracks/cylinder")) { v = GETNUM(lp->d_ntracks, tp, 1, &errstr); if (errstr) { warnx("line %d: bad %s: %s", lineno, cp, tp); errors++; } else lp->d_ntracks = v; continue; } if (!strcmp(cp, "cylinders")) { v = GETNUM(lp->d_ncylinders, tp, 1, &errstr); if (errstr) { warnx("line %d: bad %s: %s", lineno, cp, tp); errors++; } else lp->d_ncylinders = v; continue; } /* Ignore fields that are no longer in the disklabel. */ if (!strcmp(cp, "rpm") || !strcmp(cp, "interleave") || !strcmp(cp, "trackskew") || !strcmp(cp, "cylinderskew") || !strcmp(cp, "headswitch") || !strcmp(cp, "track-to-track seek")) continue; /* Ignore fields that are forcibly set when label is read. */ if (!strcmp(cp, "total sectors") || !strcmp(cp, "boundstart") || !strcmp(cp, "boundend")) continue; if ('a' <= *cp && *cp <= 'z' && cp[1] == '\0') { unsigned int part = *cp - 'a'; if (part >= lp->d_npartitions) { if (part >= MAXPARTITIONS) { warnx("line %d: bad partition name: %s", lineno, cp); errors++; continue; } else { lp->d_npartitions = part + 1; } } pp = &lp->d_partitions[part]; #define NXTNUM(n, field, errstr) { \ if (tp == NULL) { \ warnx("line %d: too few fields", lineno); \ errors++; \ break; \ } else \ cp = tp, tp = word(cp), (n) = GETNUM(field, cp, 0, errstr); \ } NXTNUM(lv, lv, &errstr); if (errstr) { warnx("line %d: bad partition size: %s", lineno, cp); errors++; } else { DL_SETPSIZE(pp, lv); } NXTNUM(lv, lv, &errstr); if (errstr) { warnx("line %d: bad partition offset: %s", lineno, cp); errors++; } else { DL_SETPOFFSET(pp, lv); } if (tp == NULL) { pp->p_fstype = FS_UNUSED; goto gottype; } cp = tp, tp = word(cp); cpp = fstypenames; for (; cpp < &fstypenames[FSMAXTYPES]; cpp++) if ((s = *cpp) && !strcasecmp(s, cp)) { pp->p_fstype = cpp - fstypenames; goto gottype; } if (isdigit((unsigned char)*cp)) v = GETNUM(pp->p_fstype, cp, 0, &errstr); else v = FSMAXTYPES; if (errstr || v >= FSMAXTYPES) { warnx("line %d: warning, unknown filesystem type: %s", lineno, cp); v = FS_UNUSED; } pp->p_fstype = v; gottype: switch (pp->p_fstype) { case FS_UNUSED: /* XXX */ if (tp == NULL) /* ok to skip fsize/bsize */ break; NXTNUM(fsize, fsize, &errstr); if (fsize == 0) break; NXTNUM(v, v, &errstr); pp->p_fragblock = DISKLABELV1_FFS_FRAGBLOCK(fsize, v / fsize); break; case FS_BSDFFS: NXTNUM(fsize, fsize, &errstr); if (fsize == 0) break; NXTNUM(v, v, &errstr); pp->p_fragblock = DISKLABELV1_FFS_FRAGBLOCK(fsize, v / fsize); NXTNUM(pp->p_cpg, pp->p_cpg, &errstr); break; default: break; } if (mp) mountpoints[part] = strdup(mp); continue; } warnx("line %d: unknown field: %s", lineno, cp); errors++; next: ; } errors += checklabel(lp); if (errors > 0) mpcopy(mountpoints, omountpoints); mpfree(omountpoints); return (errors > 0); }
void main(int argc, char **argv) { int isnew; char *id, buf[Maxmsg], home[Maxmsg], prompt[100], *hexHi; char *pass, *passck; long expsecs; mpint *H = mpnew(0), *Hi = mpnew(0); PW *pw; Tm *tm; ARGBEGIN{ case 'v': verbose++; break; }ARGEND; if(argc!=1){ fprint(2, "usage: secuser [-v] <user>\n"); exits("usage"); } ensure_exists(SECSTORE_DIR, DMDIR|0755L); snprint(home, sizeof(home), "%s/who", SECSTORE_DIR); ensure_exists(home, DMDIR|0755L); snprint(home, sizeof(home), "%s/store", SECSTORE_DIR); ensure_exists(home, DMDIR|0700L); id = argv[0]; if(verbose) fprint(2,"secuser %s\n", id); if((pw = getPW(id,1)) == nil){ isnew = 1; print("new account (because %s/%s %r)\n", SECSTORE_DIR, id); pw = emalloc(sizeof(*pw)); pw->id = estrdup(id); snprint(home, sizeof(home), "%s/store/%s", SECSTORE_DIR, id); if(access(home, AEXIST) == 0) sysfatal("new user, but directory %s already exists", home); }else{ isnew = 0; } /* get main password for id */ for(;;){ if(isnew) snprint(prompt, sizeof(prompt), "%s password: "******"%s password [default = don't change]: ", id); pass = getpassm(prompt); if(pass == nil) sysfatal("getpassm failed"); if(verbose) print("%ld characters\n", strlen(pass)); if(pass[0] == '\0' && isnew == 0) break; if(strlen(pass) >= 7) break; print("password must be at least 7 characters\n"); } if(pass[0] != '\0'){ snprint(prompt, sizeof(prompt), "retype password: "******"confirming...\n"); passck = getpassm(prompt); if(passck == nil) sysfatal("getpassm failed"); if(strcmp(pass, passck) != 0) sysfatal("passwords didn't match"); memset(passck, 0, strlen(passck)); free(passck); hexHi = PAK_Hi(id, pass, H, Hi); memset(pass, 0, strlen(pass)); free(pass); free(hexHi); mpfree(H); pw->Hi = Hi; } /* get expiration time (midnight of date specified) */ if(isnew) expsecs = time(0) + 365*24*60*60; else expsecs = pw->expire; for(;;){ tm = localtime(expsecs); print("expires [DDMMYYYY, default = %2.2d%2.2d%4.4d]: ", tm->mday, tm->mon+1, tm->year+1900); userinput(buf, sizeof(buf)); if(strlen(buf) == 0) break; if(strlen(buf) != 8){ print("!bad date format: %s\n", buf); continue; } tm->mday = (buf[0]-'0')*10 + (buf[1]-'0'); if(tm->mday > 31 || tm->mday < 1){ print("!bad day of month: %d\n", tm->mday); continue; } tm->mon = (buf[2]-'0')*10 + (buf[3]-'0') - 1; if(tm->mon > 11 || tm->mon < 0){ print("!bad month: %d\n", tm->mon + 1); continue; } tm->year = atoi(buf+4) - 1900; if(tm->year < 70){ print("!bad year: %d\n", tm->year + 1900); continue; } tm->sec = 59; tm->min = 59; tm->hour = 23; tm->yday = 0; expsecs = tm2sec(tm); break; } pw->expire = expsecs; /* failed logins */ if(pw->failed != 0 ) print("clearing %d failed login attempts\n", pw->failed); pw->failed = 0; /* status bits */ if(isnew) pw->status = Enabled; for(;;){ print("Enabled or Disabled [default %s]: ", (pw->status & Enabled) ? "Enabled" : "Disabled" ); userinput(buf, sizeof(buf)); if(strlen(buf) == 0) break; if(buf[0]=='E' || buf[0]=='e'){ pw->status |= Enabled; break; } if(buf[0]=='D' || buf[0]=='d'){ pw->status = pw->status & ~Enabled; break; } } for(;;){ print("require STA? [default %s]: ", (pw->status & STA) ? "yes" : "no" ); userinput(buf, sizeof(buf)); if(strlen(buf) == 0) break; if(buf[0]=='Y' || buf[0]=='y'){ pw->status |= STA; break; } if(buf[0]=='N' || buf[0]=='n'){ pw->status = pw->status & ~STA; break; } } /* free form field */ if(isnew) pw->other = nil; print("comments [default = %s]: ", (pw->other == nil) ? "" : pw->other); userinput(buf, 72); /* 72 comes from password.h */ if(buf[0]) if((pw->other = strdup(buf)) == nil) sysfatal("strdup"); syslog(0, LOG, "CHANGELOGIN for '%s'", pw->id); if(putPW(pw) < 0) sysfatal("can't write password file: %r"); else{ print("change written\n"); if(isnew && create(home, OREAD, DMDIR | 0775L) < 0) sysfatal("unable to create %s: %r", home); } exits(""); }
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); }
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); }
void mpexp(mpint *b, mpint *e, mpint *m, mpint *res) { mpint *t[2]; int tofree; mpdigit d, bit; int i, j; t[0] = mpcopy(b); t[1] = res; tofree = 0; if(res == b){ b = mpcopy(b); tofree |= Freeb; } if(res == e){ e = mpcopy(e); tofree |= Freee; } if(res == m){ m = mpcopy(m); tofree |= Freem; } // skip first bit i = e->top-1; d = e->p[i]; for(bit = mpdighi; (bit & d) == 0; bit >>= 1) ; bit >>= 1; j = 0; for(;;){ for(; bit != 0; bit >>= 1){ mpmul(t[j], t[j], t[j^1]); if(bit & d) mpmul(t[j^1], b, t[j]); else j ^= 1; if(m != nil && t[j]->top > m->top){ mpmod(t[j], m, t[j^1]); j ^= 1; } } if(--i < 0) break; bit = mpdighi; d = e->p[i]; } if(m != nil){ mpmod(t[j], m, t[j^1]); j ^= 1; } if(t[j] == res){ mpfree(t[j^1]); } else { mpassign(t[j], res); mpfree(t[j]); } if(tofree){ if(tofree & Freeb) mpfree(b); if(tofree & Freee) mpfree(e); if(tofree & Freem) mpfree(m); } }
mpint* mpfactorial(ulong n) { int i; ulong k; unsigned cnt; int max, mmax; mpdigit p, pp[2]; mpint *r, *s, *stk[31]; cnt = 0; max = mmax = -1; p = 1; r = mpnew(0); for(k=2; k<=n; k++) { pp[0] = 0; pp[1] = 0; mpvecdigmuladd(&p, 1, (mpdigit)k, pp); if(pp[1] == 0) /* !overflow */ p = pp[0]; else { cnt++; if((cnt & 1) == 0) { s = stk[max]; mpbits(r, Dbits*(s->top+1+1)); memset(r->p, 0, Dbytes*(s->top+1+1)); mpvecmul(s->p, s->top, &p, 1, r->p); r->sign = 1; r->top = s->top+1+1; /* XXX: norm */ mpassign(r, s); for(i=4; (cnt & (i-1)) == 0; i=i<<1) { mpmul(stk[max], stk[max-1], r); mpassign(r, stk[max-1]); max--; } } else { max++; if(max > mmax) { mmax++; if(max > nelem(stk)) abort(); stk[max] = mpnew(Dbits); } stk[max]->top = 1; stk[max]->p[0] = p; } p = (mpdigit)k; } } if(max < 0) { mpbits(r, Dbits); r->top = 1; r->sign = 1; r->p[0] = p; } else { s = stk[max--]; mpbits(r, Dbits*(s->top+1+1)); memset(r->p, 0, Dbytes*(s->top+1+1)); mpvecmul(s->p, s->top, &p, 1, r->p); r->sign = 1; r->top = s->top+1+1; /* XXX: norm */ } while(max >= 0) mpmul(r, stk[max--], r); for(max=mmax; max>=0; max--) mpfree(stk[max]); mpnorm(r); return r; }
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; }
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; }
// extended binary gcd // // For a anv b it solves, v = gcd(a,b) and finds x and y s.t. // ax + by = v // // Handbook of Applied Cryptography, Menezes et al, 1997, pg 608. void mpextendedgcd(mpint *a, mpint *b, mpint *v, mpint *x, mpint *y) { mpint *u, *A, *B, *C, *D; int g; if(a->top == 0){ mpassign(b, v); mpassign(mpone, y); mpassign(mpzero, x); return; } if(b->top == 0){ mpassign(a, v); mpassign(mpone, x); mpassign(mpzero, y); return; } g = 0; a = mpcopy(a); b = mpcopy(b); while(iseven(a) && iseven(b)){ mpright(a, 1, a); mpright(b, 1, b); g++; } u = mpcopy(a); mpassign(b, v); A = mpcopy(mpone); B = mpcopy(mpzero); C = mpcopy(mpzero); D = mpcopy(mpone); for(;;) { // print("%B %B %B %B %B %B\n", u, v, A, B, C, D); while(iseven(u)){ mpright(u, 1, u); if(!iseven(A) || !iseven(B)) { mpadd(A, b, A); mpsub(B, a, B); } mpright(A, 1, A); mpright(B, 1, B); } // print("%B %B %B %B %B %B\n", u, v, A, B, C, D); while(iseven(v)){ mpright(v, 1, v); if(!iseven(C) || !iseven(D)) { mpadd(C, b, C); mpsub(D, a, D); } mpright(C, 1, C); mpright(D, 1, D); } // print("%B %B %B %B %B %B\n", u, v, A, B, C, D); if(mpcmp(u, v) >= 0){ mpsub(u, v, u); mpsub(A, C, A); mpsub(B, D, B); } else { mpsub(v, u, v); mpsub(C, A, C); mpsub(D, B, D); } if(u->top == 0) break; } mpassign(C, x); mpassign(D, y); mpleft(v, g, v); mpfree(A); mpfree(B); mpfree(C); mpfree(D); mpfree(u); mpfree(a); mpfree(b); }
static int chpasswd(AuthConn *c, char *id) { ulong len; int rv = -1, newpasslen = 0; mpint *H, *Hi; uchar *memfile; char *newpass, *passck; char *list, *cur, *next, *hexHi; char *f[8], prompt[128]; H = mpnew(0); Hi = mpnew(0); /* changing our password is vulnerable to connection failure */ for(;;){ snprint(prompt, sizeof(prompt), "new password for %s: ", id); newpass = readcons(prompt, nil, 1); if(newpass == nil) goto Out; if(strlen(newpass) >= 7) break; else if(strlen(newpass) == 0){ fprint(2, "!password change aborted\n"); goto Out; } print("!password must be at least 7 characters\n"); } newpasslen = strlen(newpass); snprint(prompt, sizeof(prompt), "retype password: "******"readcons failed\n"); goto Out; } if(strcmp(passck, newpass) != 0){ fprint(2, "passwords didn't match\n"); goto Out; } c->conn->write(c->conn, (uchar*)"CHPASS", strlen("CHPASS")); hexHi = PAK_Hi(id, newpass, H, Hi); c->conn->write(c->conn, (uchar*)hexHi, strlen(hexHi)); free(hexHi); mpfree(H); mpfree(Hi); if(getfile(c->conn, ".", (uchar **)(void*)&list, &len, nil, 0) < 0){ fprint(2, "directory listing failed.\n"); goto Out; } /* Loop over files and reencrypt them; try to keep going after error */ for(cur=list; (next=strchr(cur, '\n')) != nil; cur=next+1){ *next = '\0'; if(tokenize(cur, f, nelem(f))< 1) break; fprint(2, "reencrypting '%s'\n", f[0]); if(getfile(c->conn, f[0], &memfile, &len, (uchar*)c->pass, c->passlen) < 0){ fprint(2, "getfile of '%s' failed\n", f[0]); continue; } if(putfile(c->conn, f[0], memfile, len, (uchar*)newpass, newpasslen) < 0) fprint(2, "putfile of '%s' failed\n", f[0]); free(memfile); } free(list); c->conn->write(c->conn, (uchar*)"BYE", 3); rv = 0; Out: if(newpass != nil){ memset(newpass, 0, newpasslen); free(newpass); } c->conn->free(c->conn); return rv; }
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; }