/* * This file is part of the UCB release of Plan 9. It is subject to the license * terms in the LICENSE file found in the top-level directory of this * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No * part of the UCB release of Plan 9, including this file, may be copied, * modified, propagated, or distributed except according to the terms contained * in the LICENSE file. */ #include <u.h>#include <libc.h>#include <mp.h>#include <libsec.h>#include <fcall.h>#include <thread.h>#include <9p.h>#include <auth.h>#include <ip.h>#include <pool.h>#include "netssh.h" #undef VERIFYKEYS /* TODO until it's fixed */ enum { Errnokey = -2, /* no key on keyring */ Errnoverify, /* factotum found a key, but verification failed */ Errfactotum, /* factotum failure (e.g., no key) */ Errnone, /* key verified */}; static int dh_server(Conn *, Packet *, mpint *, int);static void genkeys(Conn *, uchar [], mpint *); /* * Second Oakley Group from RFC 2409 */static char *group1p = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381" "FFFFFFFFFFFFFFFF"; /* * 2048-bit MODP group (id 14) from RFC 3526*/static char *group14p = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" "83655D23DCA3AD961C62F356208552BB9ED529077096966D" "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" "DE2BCBF6955817183995497CEA956AE515D2261898FA0510" "15728E5A8AACAA68FFFFFFFFFFFFFFFF"; mpint *two, *p1, *p14;int nokeyverify; static DSApriv mydsskey;static RSApriv myrsakey; voiddh_init(PKA *pkas[]){ char *buf, *p, *st, *end; int fd, n, k; if(debug > 1) sshdebug(nil, "dh_init"); k = 0; pkas[k] = nil; fmtinstall('M', mpfmt); two = strtomp("2", nil, 10, nil); p1 = strtomp(group1p, nil, 16, nil); p14 = strtomp(group14p, nil, 16, nil); /* * this really should be done through factotum */ p = getenv("rsakey"); if (p != nil) { remove("/env/rsakey"); st = buf = p; end = buf + strlen(p); } else { /* * it would be better to use bio and rdline here instead of * reading all of factotum's contents into memory at once. */ buf = emalloc9p(Maxfactotum); fd = open("rsakey", OREAD); if (fd < 0 && (fd = open("/mnt/factotum/ctl", OREAD)) < 0) goto norsa; n = readn(fd, buf, Maxfactotum - 1); buf[n >= 0? n: 0] = 0; close(fd); assert(n < Maxfactotum - 1); st = strstr(buf, "proto=rsa"); if (st == nil) { sshlog(nil, "no proto=rsa key in factotum"); goto norsa; } end = st; for (; st > buf && *st != '\n'; --st) ; for (; end < buf + Maxfactotum && *end != '\n'; ++end) ; } p = strstr(st, " n="); if (p == nil || p > end) { sshlog(nil, "no key (n) found"); free(buf); return; } myrsakey.pub.n = strtomp(p+3, nil, 16, nil); if (debug > 1) sshdebug(nil, "n=%M", myrsakey.pub.n); p = strstr(st, " ek="); if (p == nil || p > end) { sshlog(nil, "no key (ek) found"); free(buf); return; } pkas[k++] = &rsa_pka; pkas[k] = nil; myrsakey.pub.ek = strtomp(p+4, nil, 16, nil); if (debug > 1) sshdebug(nil, "ek=%M", myrsakey.pub.ek); p = strstr(st, " !dk="); if (p == nil) { p = strstr(st, "!dk?"); if (p == nil || p > end) { // sshlog(nil, "no key (dk) found"); free(buf); return; } goto norsa; } myrsakey.dk = strtomp(p+5, nil, 16, nil); if (debug > 1) sshdebug(nil, "dk=%M", myrsakey.dk);norsa: free(buf); p = getenv("dsskey"); if (p != nil) { remove("/env/dsskey"); buf = p; end = buf + strlen(p); } else { /* * it would be better to use bio and rdline here instead of * reading all of factotum's contents into memory at once. */ buf = emalloc9p(Maxfactotum); fd = open("dsskey", OREAD); if (fd < 0 && (fd = open("/mnt/factotum/ctl", OREAD)) < 0) return; n = readn(fd, buf, Maxfactotum - 1); buf[n >= 0? n: 0] = 0; close(fd); assert(n < Maxfactotum - 1); st = strstr(buf, "proto=dsa"); if (st == nil) { sshlog(nil, "no proto=dsa key in factotum"); free(buf); return; } end = st; for (; st > buf && *st != '\n'; --st) ; for (; end < buf + Maxfactotum && *end != '\n'; ++end) ; } p = strstr(buf, " p="); if (p == nil || p > end) { sshlog(nil, "no key (p) found"); free(buf); return; } mydsskey.pub.p = strtomp(p+3, nil, 16, nil); p = strstr(buf, " q="); if (p == nil || p > end) { sshlog(nil, "no key (q) found"); free(buf); return; } mydsskey.pub.q = strtomp(p+3, nil, 16, nil); p = strstr(buf, " alpha="); if (p == nil || p > end) { sshlog(nil, "no key (g) found"); free(buf); return; } mydsskey.pub.alpha = strtomp(p+7, nil, 16, nil); p = strstr(buf, " key="); if (p == nil || p > end) { sshlog(nil, "no key (y) found"); free(buf); return; } mydsskey.pub.key = strtomp(p+5, nil, 16, nil); pkas[k++] = &dss_pka; pkas[k] = nil; p = strstr(buf, " !secret="); if (p == nil) { p = strstr(buf, "!secret?"); if (p == nil || p > end) sshlog(nil, "no key (x) found"); free(buf); return; } mydsskey.secret = strtomp(p+9, nil, 16, nil); free(buf);} static Packet *rsa_ks(Conn *c){ Packet *ks; if (myrsakey.pub.ek == nil || myrsakey.pub.n == nil) { sshlog(c, "no public RSA key info"); return nil; } ks = new_packet(c); add_string(ks, "ssh-rsa"); add_mp(ks, myrsakey.pub.ek); add_mp(ks, myrsakey.pub.n); return ks;} static voidesma_encode(uchar *h, uchar *em, int nb){ int n, i; uchar hh[SHA1dlen]; static uchar sha1der[] = { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14, }; sha1(h, SHA1dlen, hh, nil); n = nb - (nelem(sha1der) + SHA1dlen) - 3; i = 0; em[i++] = 0; em[i++] = 1; memset(em + i, 0xff, n); i += n; em[i++] = 0; memmove(em + i, sha1der, sizeof sha1der); i += sizeof sha1der; memmove(em + i, hh, SHA1dlen);} static Packet *rsa_sign(Conn *c, uchar *m, int nm){ AuthRpc *ar; Packet *sig; mpint *s, *mm; int fd, n, nbit; uchar hh[SHA1dlen]; uchar *sstr, *em; if (myrsakey.dk) { nbit = mpsignif (myrsakey.pub.n); n = (nbit + 7) / 8; sstr = emalloc9p(n); em = emalloc9p(n); /* Compute s: RFC 3447 */ esma_encode(m, em, n); mm = betomp(em, n, nil); s = mpnew(nbit); mpexp(mm, myrsakey.dk, myrsakey.pub.n, s); mptobe(s, sstr, n, nil); mpfree(mm); mpfree(s); free(em); } else { fd = open("/mnt/factotum/rpc", ORDWR); if (fd < 0) return nil; sha1(m, nm, hh, nil); ar = auth_allocrpc(fd); if (ar == nil || auth_rpc(ar, "start", "role=sign proto=rsa", 19) != ARok || auth_rpc(ar, "write", hh, SHA1dlen) != ARok || auth_rpc(ar, "read", nil, 0) != ARok || ar->arg == nil) { sshdebug(c, "got error in factotum: %r"); auth_freerpc(ar); close(fd); return nil; } sstr = emalloc9p(ar->narg); memmove(sstr, ar->arg, ar->narg); n = ar->narg; auth_freerpc(ar); close(fd); } sig = new_packet(c); add_string(sig, pkas[c->pkalg]->name); add_block(sig, sstr, n); free(sstr); return sig;} /* * 0 - If factotum failed, e.g. no key * 1 - If key is verified * -1 - If factotum found a key, but the verification fails */static intrsa_verify(Conn *c, uchar *m, int nm, char *user, char *sig, int){ int fd, n, retval, nbit; char *buf, *p, *sigblob; uchar *sstr, *em; uchar hh[SHA1dlen]; mpint *s, *mm, *rsa_exponent, *host_modulus; AuthRpc *ar; sshdebug(c, "in rsa_verify for connection: %d", c->id); SET(rsa_exponent, host_modulus); USED(rsa_exponent, host_modulus); if (0 && rsa_exponent) { nbit = mpsignif(host_modulus); n = (nbit + 7) / 8; em = emalloc9p(n); /* Compute s: RFC 3447 */ esma_encode(m, em, n); mm = betomp(em, n, nil); s = mpnew(1024); mpexp(mm, rsa_exponent, host_modulus, s); sstr = emalloc9p(n); mptobe(s, sstr, n, nil); free(em); mpfree(mm); mpfree(s); retval = memcmp(sig, sstr, n); free(sstr); retval = (retval == 0); } else { retval = 1; fd = open("/mnt/factotum/rpc", ORDWR); if (fd < 0) { sshdebug(c, "could not open factotum RPC: %r"); return 0; } buf = emalloc9p(Blobsz / 2); sigblob = emalloc9p(Blobsz); p = (char *)get_string(nil, (uchar *)sig, buf, Blobsz / 2, nil); get_string(nil, (uchar *)p, sigblob, Blobsz, &n); sha1(m, nm, hh, nil); if (user != nil) p = smprint("role=verify proto=rsa user=%s", user); else p = smprint("role=verify proto=rsa sys=%s", c->remote); ar = auth_allocrpc(fd); if (ar == nil || auth_rpc(ar, "start", p, strlen(p)) != ARok || auth_rpc(ar, "write", hh, SHA1dlen) != ARok || auth_rpc(ar, "write", sigblob, n) != ARok || auth_rpc(ar, "read", nil, 0) != ARok) { sshdebug(c, "got error in factotum: %r"); retval = 0; } else { sshdebug(c, "factotum returned %s", ar->ibuf); if (strstr(ar->ibuf, "does not verify") != nil) retval = -1; } if (ar != nil) auth_freerpc(ar); free(p); close(fd); free(sigblob); free(buf); } return retval;} static Packet *dss_ks(Conn *c){ Packet *ks; if (mydsskey.pub.p == nil) return nil; ks = new_packet(c); add_string(ks, "ssh-dss"); add_mp(ks, mydsskey.pub.p); add_mp(ks, mydsskey.pub.q); add_mp(ks, mydsskey.pub.alpha); add_mp(ks, mydsskey.pub.key); return ks;} static Packet *dss_sign(Conn *c, uchar *m, int nm){ AuthRpc *ar; DSAsig *s; Packet *sig; mpint *mm; int fd; uchar sstr[2*SHA1dlen]; sha1(m, nm, sstr, nil); sig = new_packet(c); add_string(sig, pkas[c->pkalg]->name); if (mydsskey.secret) { mm = betomp(sstr, SHA1dlen, nil); s = dsasign(&mydsskey, mm); mptobe(s->r, sstr, SHA1dlen, nil); mptobe(s->s, sstr+SHA1dlen, SHA1dlen, nil); dsasigfree(s); mpfree(mm); } else { fd = open("/mnt/factotum/rpc", ORDWR); if (fd < 0) return nil; ar = auth_allocrpc(fd); if (ar == nil || auth_rpc(ar, "start", "role=sign proto=dsa", 19) != ARok || auth_rpc(ar, "write", sstr, SHA1dlen) != ARok || auth_rpc(ar, "read", nil, 0) != ARok) { sshdebug(c, "got error in factotum: %r"); auth_freerpc(ar); close(fd); return nil; } memmove(sstr, ar->arg, ar->narg); auth_freerpc(ar); close(fd); } add_block(sig, sstr, 2*SHA1dlen); return sig;} static intdss_verify(Conn *c, uchar *m, int nm, char *user, char *sig, int nsig){ sshdebug(c, "in dss_verify for connection: %d", c->id); USED(m, nm, user, sig, nsig); return 0;} static intdh_server1(Conn *c, Packet *pack1){ return dh_server(c, pack1, p1, 1024);} static intdh_server14(Conn *c, Packet *pack1){ return dh_server(c, pack1, p14, 2048);} static intdh_server(Conn *c, Packet *pack1, mpint *grp, int nbit){ Packet *pack2, *ks, *sig; mpint *y, *e, *f, *k; int n, ret; uchar h[SHA1dlen]; ret = -1; qlock(&c->l); f = mpnew(nbit); k = mpnew(nbit); /* Compute f: RFC4253 */ y = mprand(nbit / 8, genrandom, nil); if (debug > 1) sshdebug(c, "y=%M", y); mpexp(two, y, grp, f); if (debug > 1) sshdebug(c, "f=%M", f); /* Compute k: RFC4253 */ if (debug > 1) dump_packet(pack1); e = get_mp(pack1->payload+1); if (debug > 1) sshdebug(c, "e=%M", e); mpexp(e, y, grp, k); if (debug > 1) sshdebug(c, "k=%M", k); /* Compute H: RFC 4253 */Lines 1–500 of 957. Load more
/* * This file is part of the UCB release of Plan 9. It is subject to the license * terms in the LICENSE file found in the top-level directory of this * distribution and at http://akaros.cs.berkeley.edu/files/Plan9License. No * part of the UCB release of Plan 9, including this file, may be copied, * modified, propagated, or distributed except according to the terms contained * in the LICENSE file. */ #include <u.h> #include <libc.h> #include <mp.h> #include <libsec.h> #include <fcall.h> #include <thread.h> #include <9p.h> #include <auth.h> #include <ip.h> #include <pool.h> #include "netssh.h" #undef VERIFYKEYS /* TODO until it's fixed */ enum { Errnokey = -2, /* no key on keyring */ Errnoverify, /* factotum found a key, but verification failed */ Errfactotum, /* factotum failure (e.g., no key) */ Errnone, /* key verified */ }; static int dh_server(Conn *, Packet *, mpint *, int); static void genkeys(Conn *, uchar [], mpint *); /* * Second Oakley Group from RFC 2409 */ static char *group1p = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE65381" "FFFFFFFFFFFFFFFF"; /* * 2048-bit MODP group (id 14) from RFC 3526 */ static char *group14p = "FFFFFFFFFFFFFFFFC90FDAA22168C234C4C6628B80DC1CD1" "29024E088A67CC74020BBEA63B139B22514A08798E3404DD" "EF9519B3CD3A431B302B0A6DF25F14374FE1356D6D51C245" "E485B576625E7EC6F44C42E9A637ED6B0BFF5CB6F406B7ED" "EE386BFB5A899FA5AE9F24117C4B1FE649286651ECE45B3D" "C2007CB8A163BF0598DA48361C55D39A69163FA8FD24CF5F" "83655D23DCA3AD961C62F356208552BB9ED529077096966D" "670C354E4ABC9804F1746C08CA18217C32905E462E36CE3B" "E39E772C180E86039B2783A2EC07A28FB5C55DF06F4C52C9" "DE2BCBF6955817183995497CEA956AE515D2261898FA0510" "15728E5A8AACAA68FFFFFFFFFFFFFFFF"; mpint *two, *p1, *p14; int nokeyverify; static DSApriv mydsskey; static RSApriv myrsakey; void dh_init(PKA *pkas[]) { char *buf, *p, *st, *end; int fd, n, k; if(debug > 1) sshdebug(nil, "dh_init"); k = 0; pkas[k] = nil; fmtinstall('M', mpfmt); two = strtomp("2", nil, 10, nil); p1 = strtomp(group1p, nil, 16, nil); p14 = strtomp(group14p, nil, 16, nil); /* * this really should be done through factotum */ p = getenv("rsakey"); if (p != nil) { remove("/env/rsakey"); st = buf = p; end = buf + strlen(p); } else { /* * it would be better to use bio and rdline here instead of * reading all of factotum's contents into memory at once. */ buf = emalloc9p(Maxfactotum); fd = open("rsakey", OREAD); if (fd < 0 && (fd = open("/mnt/factotum/ctl", OREAD)) < 0) goto norsa; n = readn(fd, buf, Maxfactotum - 1); buf[n >= 0? n: 0] = 0; close(fd); assert(n < Maxfactotum - 1); st = strstr(buf, "proto=rsa"); if (st == nil) { sshlog(nil, "no proto=rsa key in factotum"); goto norsa; } end = st; for (; st > buf && *st != '\n'; --st) ; for (; end < buf + Maxfactotum && *end != '\n'; ++end) ; } p = strstr(st, " n="); if (p == nil || p > end) { sshlog(nil, "no key (n) found"); free(buf); return; } myrsakey.pub.n = strtomp(p+3, nil, 16, nil); if (debug > 1) sshdebug(nil, "n=%M", myrsakey.pub.n); p = strstr(st, " ek="); if (p == nil || p > end) { sshlog(nil, "no key (ek) found"); free(buf); return; } pkas[k++] = &rsa_pka; pkas[k] = nil; myrsakey.pub.ek = strtomp(p+4, nil, 16, nil); if (debug > 1) sshdebug(nil, "ek=%M", myrsakey.pub.ek); p = strstr(st, " !dk="); if (p == nil) { p = strstr(st, "!dk?"); if (p == nil || p > end) { // sshlog(nil, "no key (dk) found"); free(buf); return; } goto norsa; } myrsakey.dk = strtomp(p+5, nil, 16, nil); if (debug > 1) sshdebug(nil, "dk=%M", myrsakey.dk); norsa: free(buf); p = getenv("dsskey"); if (p != nil) { remove("/env/dsskey"); buf = p; end = buf + strlen(p); } else { /* * it would be better to use bio and rdline here instead of * reading all of factotum's contents into memory at once. */ buf = emalloc9p(Maxfactotum); fd = open("dsskey", OREAD); if (fd < 0 && (fd = open("/mnt/factotum/ctl", OREAD)) < 0) return; n = readn(fd, buf, Maxfactotum - 1); buf[n >= 0? n: 0] = 0; close(fd); assert(n < Maxfactotum - 1); st = strstr(buf, "proto=dsa"); if (st == nil) { sshlog(nil, "no proto=dsa key in factotum"); free(buf); return; } end = st; for (; st > buf && *st != '\n'; --st) ; for (; end < buf + Maxfactotum && *end != '\n'; ++end) ; } p = strstr(buf, " p="); if (p == nil || p > end) { sshlog(nil, "no key (p) found"); free(buf); return; } mydsskey.pub.p = strtomp(p+3, nil, 16, nil); p = strstr(buf, " q="); if (p == nil || p > end) { sshlog(nil, "no key (q) found"); free(buf); return; } mydsskey.pub.q = strtomp(p+3, nil, 16, nil); p = strstr(buf, " alpha="); if (p == nil || p > end) { sshlog(nil, "no key (g) found"); free(buf); return; } mydsskey.pub.alpha = strtomp(p+7, nil, 16, nil); p = strstr(buf, " key="); if (p == nil || p > end) { sshlog(nil, "no key (y) found"); free(buf); return; } mydsskey.pub.key = strtomp(p+5, nil, 16, nil); pkas[k++] = &dss_pka; pkas[k] = nil; p = strstr(buf, " !secret="); if (p == nil) { p = strstr(buf, "!secret?"); if (p == nil || p > end) sshlog(nil, "no key (x) found"); free(buf); return; } mydsskey.secret = strtomp(p+9, nil, 16, nil); free(buf); } static Packet * rsa_ks(Conn *c) { Packet *ks; if (myrsakey.pub.ek == nil || myrsakey.pub.n == nil) { sshlog(c, "no public RSA key info"); return nil; } ks = new_packet(c); add_string(ks, "ssh-rsa"); add_mp(ks, myrsakey.pub.ek); add_mp(ks, myrsakey.pub.n); return ks; } static void esma_encode(uchar *h, uchar *em, int nb) { int n, i; uchar hh[SHA1dlen]; static uchar sha1der[] = { 0x30, 0x21, 0x30, 0x09, 0x06, 0x05, 0x2b, 0x0e, 0x03, 0x02, 0x1a, 0x05, 0x00, 0x04, 0x14, }; sha1(h, SHA1dlen, hh, nil); n = nb - (nelem(sha1der) + SHA1dlen) - 3; i = 0; em[i++] = 0; em[i++] = 1; memset(em + i, 0xff, n); i += n; em[i++] = 0; memmove(em + i, sha1der, sizeof sha1der); i += sizeof sha1der; memmove(em + i, hh, SHA1dlen); } static Packet * rsa_sign(Conn *c, uchar *m, int nm) { AuthRpc *ar; Packet *sig; mpint *s, *mm; int fd, n, nbit; uchar hh[SHA1dlen]; uchar *sstr, *em; if (myrsakey.dk) { nbit = mpsignif (myrsakey.pub.n); n = (nbit + 7) / 8; sstr = emalloc9p(n); em = emalloc9p(n); /* Compute s: RFC 3447 */ esma_encode(m, em, n); mm = betomp(em, n, nil); s = mpnew(nbit); mpexp(mm, myrsakey.dk, myrsakey.pub.n, s); mptobe(s, sstr, n, nil); mpfree(mm); mpfree(s); free(em); } else { fd = open("/mnt/factotum/rpc", ORDWR); if (fd < 0) return nil; sha1(m, nm, hh, nil); ar = auth_allocrpc(fd); if (ar == nil || auth_rpc(ar, "start", "role=sign proto=rsa", 19) != ARok || auth_rpc(ar, "write", hh, SHA1dlen) != ARok || auth_rpc(ar, "read", nil, 0) != ARok || ar->arg == nil) { sshdebug(c, "got error in factotum: %r"); auth_freerpc(ar); close(fd); return nil; } sstr = emalloc9p(ar->narg); memmove(sstr, ar->arg, ar->narg); n = ar->narg; auth_freerpc(ar); close(fd); } sig = new_packet(c); add_string(sig, pkas[c->pkalg]->name); add_block(sig, sstr, n); free(sstr); return sig; } /* * 0 - If factotum failed, e.g. no key * 1 - If key is verified * -1 - If factotum found a key, but the verification fails */ static int rsa_verify(Conn *c, uchar *m, int nm, char *user, char *sig, int) { int fd, n, retval, nbit; char *buf, *p, *sigblob; uchar *sstr, *em; uchar hh[SHA1dlen]; mpint *s, *mm, *rsa_exponent, *host_modulus; AuthRpc *ar; sshdebug(c, "in rsa_verify for connection: %d", c->id); SET(rsa_exponent, host_modulus); USED(rsa_exponent, host_modulus); if (0 && rsa_exponent) { nbit = mpsignif(host_modulus); n = (nbit + 7) / 8; em = emalloc9p(n); /* Compute s: RFC 3447 */ esma_encode(m, em, n); mm = betomp(em, n, nil); s = mpnew(1024); mpexp(mm, rsa_exponent, host_modulus, s); sstr = emalloc9p(n); mptobe(s, sstr, n, nil); free(em); mpfree(mm); mpfree(s); retval = memcmp(sig, sstr, n); free(sstr); retval = (retval == 0); } else { retval = 1; fd = open("/mnt/factotum/rpc", ORDWR); if (fd < 0) { sshdebug(c, "could not open factotum RPC: %r"); return 0; } buf = emalloc9p(Blobsz / 2); sigblob = emalloc9p(Blobsz); p = (char *)get_string(nil, (uchar *)sig, buf, Blobsz / 2, nil); get_string(nil, (uchar *)p, sigblob, Blobsz, &n); sha1(m, nm, hh, nil); if (user != nil) p = smprint("role=verify proto=rsa user=%s", user); else p = smprint("role=verify proto=rsa sys=%s", c->remote); ar = auth_allocrpc(fd); if (ar == nil || auth_rpc(ar, "start", p, strlen(p)) != ARok || auth_rpc(ar, "write", hh, SHA1dlen) != ARok || auth_rpc(ar, "write", sigblob, n) != ARok || auth_rpc(ar, "read", nil, 0) != ARok) { sshdebug(c, "got error in factotum: %r"); retval = 0; } else { sshdebug(c, "factotum returned %s", ar->ibuf); if (strstr(ar->ibuf, "does not verify") != nil) retval = -1; } if (ar != nil) auth_freerpc(ar); free(p); close(fd); free(sigblob); free(buf); } return retval; } static Packet * dss_ks(Conn *c) { Packet *ks; if (mydsskey.pub.p == nil) return nil; ks = new_packet(c); add_string(ks, "ssh-dss"); add_mp(ks, mydsskey.pub.p); add_mp(ks, mydsskey.pub.q); add_mp(ks, mydsskey.pub.alpha); add_mp(ks, mydsskey.pub.key); return ks; } static Packet * dss_sign(Conn *c, uchar *m, int nm) { AuthRpc *ar; DSAsig *s; Packet *sig; mpint *mm; int fd; uchar sstr[2*SHA1dlen]; sha1(m, nm, sstr, nil); sig = new_packet(c); add_string(sig, pkas[c->pkalg]->name); if (mydsskey.secret) { mm = betomp(sstr, SHA1dlen, nil); s = dsasign(&mydsskey, mm); mptobe(s->r, sstr, SHA1dlen, nil); mptobe(s->s, sstr+SHA1dlen, SHA1dlen, nil); dsasigfree(s); mpfree(mm); } else { fd = open("/mnt/factotum/rpc", ORDWR); if (fd < 0) return nil; ar = auth_allocrpc(fd); if (ar == nil || auth_rpc(ar, "start", "role=sign proto=dsa", 19) != ARok || auth_rpc(ar, "write", sstr, SHA1dlen) != ARok || auth_rpc(ar, "read", nil, 0) != ARok) { sshdebug(c, "got error in factotum: %r"); auth_freerpc(ar); close(fd); return nil; } memmove(sstr, ar->arg, ar->narg); auth_freerpc(ar); close(fd); } add_block(sig, sstr, 2*SHA1dlen); return sig; } static int dss_verify(Conn *c, uchar *m, int nm, char *user, char *sig, int nsig) { sshdebug(c, "in dss_verify for connection: %d", c->id); USED(m, nm, user, sig, nsig); return 0; } static int dh_server1(Conn *c, Packet *pack1) { return dh_server(c, pack1, p1, 1024); } static int dh_server14(Conn *c, Packet *pack1) { return dh_server(c, pack1, p14, 2048); } static int dh_server(Conn *c, Packet *pack1, mpint *grp, int nbit) { Packet *pack2, *ks, *sig; mpint *y, *e, *f, *k; int n, ret; uchar h[SHA1dlen]; ret = -1; qlock(&c->l); f = mpnew(nbit); k = mpnew(nbit); /* Compute f: RFC4253 */ y = mprand(nbit / 8, genrandom, nil); if (debug > 1) sshdebug(c, "y=%M", y); mpexp(two, y, grp, f); if (debug > 1) sshdebug(c, "f=%M", f); /* Compute k: RFC4253 */ if (debug > 1) dump_packet(pack1); e = get_mp(pack1->payload+1); if (debug > 1) sshdebug(c, "e=%M", e); mpexp(e, y, grp, k); if (debug > 1) sshdebug(c, "k=%M", k); /* Compute H: RFC 4253 */