| plan 9 kernel history: overview | file list | diff list |
2002/0307/port/devssl.c (diff list | history)
| 2002/0306/sys/src/9/port/devssl.c:111,116 – 2002/0307/sys/src/9/port/devssl.c:111,117 (short | long | prev | next) | ||
| 1996/1029 | static void sslhangup(Dstate*); static Dstate* dsclone(Chan *c); static void dsnew(Chan *c, Dstate **); | |
| 2002/0307 | static long sslput(Dstate *s, Block * volatile b); | |
| 1995/1217 | ||
| 2000/0325 | char *sslnames[] = { [Qclonus] "clone", | |
| 2002/0306/sys/src/9/port/devssl.c:542,581 – 2002/0307/sys/src/9/port/devssl.c:543,582 | ||
| 1997/0327 | static Block* | |
| 1998/0327 | sslbread(Chan *c, long n, ulong) | |
| 1995/1213 | { | |
| 1996/0531 |
| |
| 2002/0307 | Dstate * volatile s; | |
| 1995/1218 | Block *b; | |
| 2001/0825 | uchar consumed[3], *p; int toconsume; | |
| 1996/1029 | int len, pad; | |
| 1995/1217 | ||
| 1996/1029 |
| |
| 2002/0307 | s = dstate[CONV(c->qid)]; if(s == 0) | |
| 1996/1029 | panic("sslbread"); | |
| 2002/0307 | if(s->state == Sincomplete) | |
| 1995/1217 | error(Ebadusefd); | |
| 2001/0825 |
| |
| 2002/0307 | qlock(&s->in.q); | |
| 1995/1217 | if(waserror()){ | |
| 1996/0531 |
| |
| 2002/0307 | qunlock(&s->in.q); | |
| 1995/1217 | nexterror(); | |
| 1995/1213 | } | |
| 1995/1217 | ||
| 1996/1029 |
| |
| 2002/0307 | if(s->processed == 0){ | |
| 2001/0825 | /* * Read in the whole message. Until we've got it all, | |
| 2002/0307 | * it stays on s->unprocessed, so that if we get Eintr, | |
| 2001/0825 | * we'll pick up where we left off. */ | |
| 2002/0307 | ensure(s, &s->unprocessed, 3); s->unprocessed = pullupblock(s->unprocessed, 2); p = s->unprocessed->rp; | |
| 2001/0825 | if(p[0] & 0x80){ len = ((p[0] & 0x7f)<<8) | p[1]; | |
| 1996/1029 |
| |
| 2002/0307 | ensure(s, &s->unprocessed, len); | |
| 1995/1217 | pad = 0; | |
| 2001/0825 | toconsume = 2; | |
| 1995/1217 | } else { | |
| 2002/0306 |
| |
| 2002/0307 | s->unprocessed = pullupblock(s->unprocessed, 3); | |
| 2001/0825 | len = ((p[0] & 0x3f)<<8) | p[1]; pad = p[2]; | |
| 1996/1029 | if(pad > len){ | |
| 2002/0306/sys/src/9/port/devssl.c:584,590 – 2002/0307/sys/src/9/port/devssl.c:585,591 | ||
| 1996/1029 | } | |
| 2001/0825 | toconsume = 3; | |
| 1995/1217 | } | |
| 2002/0306 |
| |
| 2002/0307 | ensure(s, &s->unprocessed, toconsume+len); | |
| 1995/1217 | ||
| 2001/0825 | /* * Now we have a full SSL packet in the unprocessed list. | |
| 2002/0306/sys/src/9/port/devssl.c:600,660 – 2002/0307/sys/src/9/port/devssl.c:601,661 | ||
| 2001/0825 | } /* skip header */ | |
| 2002/0307 | consume(&s->unprocessed, consumed, toconsume); | |
| 2001/0825 | ||
| 2000/0913 | /* grab the next message and decode/decrypt it */ | |
| 2002/0306 |
| |
| 2002/0307 | b = qtake(&s->unprocessed, len, 0); | |
| 2000/0913 | ||
| 2002/0306 | if(blocklen(b) != len) | |
| 2001/0825 | print("devssl: sslbread got wrong count %d != %d", blocklen(b), len); | |
| 1996/1029 | if(waserror()){ | |
| 2002/0307 | qunlock(&s->in.ctlq); | |
| 2000/0913 | if(b != nil) freeb(b); | |
| 1996/1029 | nexterror(); | |
| 1995/1217 | } | |
| 1996/1029 |
| |
| 2002/0307 | qlock(&s->in.ctlq); switch(s->state){ | |
| 1996/1029 | case Sencrypting: | |
| 2001/0825 | if(b == nil) error("ssl message too short (encrypting)"); | |
| 2000/0913 |
| |
| 2002/0307 | b = decryptb(s, b); | |
| 1996/1029 | break; case Sdigesting: | |
| 2000/0913 |
| |
| 2002/0307 | b = pullupblock(b, s->diglen); | |
| 2000/0913 | if(b == nil) | |
| 2001/0825 | error("ssl message too short (digesting)"); | |
| 2000/0913 |
| |
| 2002/0307 | checkdigestb(s, b); b->rp += s->diglen; | |
| 1996/1029 | break; | |
| 1997/0618 | case Sdigenc: | |
| 2000/0913 |
| |
| 2002/0307 | b = decryptb(s, b); b = pullupblock(b, s->diglen); | |
| 2000/0913 | if(b == nil) | |
| 2001/0825 | error("ssl message too short (dig+enc)"); | |
| 2000/0913 |
| |
| 1998/0501 |
| |
| 2002/0307 | checkdigestb(s, b); b->rp += s->diglen; len -= s->diglen; | |
| 1997/0618 | break; | |
| 1995/1218 | } | |
| 1995/1217 | /* remove pad */ | |
| 1996/1029 | if(pad) | |
| 2001/0602 |
| |
| 2002/0307 | s->processed = qtake(&b, len - pad, 1); | |
| 2000/0913 | else | |
| 2002/0307 | s->processed = b; | |
| 2000/0913 | b = nil; | |
| 2002/0307 | s->in.mid++; qunlock(&s->in.ctlq); | |
| 2000/0913 | poperror(); | |
| 2001/0825 | poperror(); | |
| 1995/1217 | } | |
| 1996/1029 | /* return at most what was asked for */ | |
| 2001/0602 |
| |
| 2002/0307 | b = qtake(&s->processed, n, 0); | |
| 1995/1217 | ||
| 1996/0531 |
| |
| 2002/0307 | qunlock(&s->in.q); | |
| 1995/1217 | poperror(); return b; | |
| 2002/0306/sys/src/9/port/devssl.c:663,669 – 2002/0307/sys/src/9/port/devssl.c:664,670 | ||
| 1997/0327 | static long | |
| 1998/0319 | sslread(Chan *c, void *a, long n, vlong off) | |
| 1995/1213 | { | |
| 1996/0531 |
| |
| 2002/0307 | Block * volatile b; | |
| 1996/1029 | Block *nb; uchar *va; int i; | |
| 2002/0306/sys/src/9/port/devssl.c:683,689 – 2002/0307/sys/src/9/port/devssl.c:684,690 | ||
| 2001/0527 | sprint(buf, "%d", ft); | |
| 1996/1029 | return readstr(offset, a, n, buf); case Qdata: | |
| 2002/0307 | b = sslbread(c, n, offset); | |
| 1996/1029 | break; | |
| 1998/0417 | case Qencalgs: return readstr(offset, a, n, encalgs); | |
| 2002/0306/sys/src/9/port/devssl.c:694,712 – 2002/0307/sys/src/9/port/devssl.c:695,713 | ||
| 1995/1213 | } | |
| 1996/0223 | if(waserror()){ | |
| 1996/1029 |
| |
| 2002/0307 | freeblist(b); | |
| 1996/0223 | nexterror(); | |
| 1995/1213 | } | |
| 1996/1029 | n = 0; va = a; | |
| 2002/0307 | for(nb = b; nb; nb = nb->next){ | |
| 1996/1029 | i = BLEN(nb); memmove(va+n, nb->rp, i); n += i; } | |
| 1996/0223 | ||
| 1996/1029 |
| |
| 2002/0307 | freeblist(b); | |
| 1996/0223 | poperror(); | |
| 1995/1213 | return n; | |
| 2002/0306/sys/src/9/port/devssl.c:723,728 – 2002/0307/sys/src/9/port/devssl.c:724,759 | ||
| 1997/0618 | *buf++ = nrand(256); | |
| 1996/1029 | } | |
| 2002/0307 | static long sslbwrite(Chan *c, Block *b, ulong) { Dstate * volatile s; long rv; s = dstate[CONV(c->qid)]; if(s == nil) panic("sslbwrite"); if(s->state == Sincomplete){ freeb(b); error(Ebadusefd); } /* lock so split writes won't interleave */ if(waserror()){ qunlock(&s->out.q); nexterror(); } qlock(&s->out.q); rv = sslput(s, b); poperror(); qunlock(&s->out.q); return rv; } | |
| 1996/1029 | /* | |
| 2000/0913 | * use SSL record format, add in count, digest and/or encrypt. * the write is interruptable. if it is interrupted, we'll | |
| 2002/0306/sys/src/9/port/devssl.c:730,777 – 2002/0307/sys/src/9/port/devssl.c:761,796 | ||
| 2000/0913 | * it since we don't know if any bytes have been written. | |
| 1995/1215 | */ | |
| 1997/0327 | static long | |
| 1995/1215 |
| |
| 2002/0307 | sslput(Dstate *s, Block * volatile b) | |
| 1995/1213 | { | |
| 1996/0531 |
| |
| 1995/1213 | Block *nb; | |
| 1995/1215 | int h, n, m, pad, rv; | |
| 1995/1217 | uchar *p; | |
| 2002/0307 | int offset; | |
| 1995/1215 | ||
| 1996/0531 |
| |
| 1996/1029 |
| |
| 1995/1215 |
| |
| 1996/1029 |
| |
| 1995/1215 |
| |
| 1996/0531 |
| |
| 2000/0913 |
| |
| 1996/0531 |
| |
| 2002/0307 | if(b != nil) free(b); | |
| 1995/1215 | nexterror(); } | |
| 1996/0531 |
| |
| 1995/1215 | rv = 0; | |
| 1996/0531 |
| |
| 2002/0307 | while(b != nil){ m = n = BLEN(b); h = s->diglen + 2; | |
| 1995/1215 | ||
| 1995/1218 | /* trim to maximum block size */ | |
| 1995/1215 | pad = 0; | |
| 1996/0531 |
| |
| 1998/0501 |
| |
| 2002/0307 | if(m > s->max){ m = s->max; } else if(s->blocklen != 1){ pad = (m + s->diglen)%s->blocklen; | |
| 1995/1215 | if(pad){ | |
| 1996/0531 |
| |
| 2002/0307 | if(m > s->maxpad){ | |
| 1995/1215 | pad = 0; | |
| 1996/0531 |
| |
| 2002/0307 | m = s->maxpad; | |
| 1995/1218 | } else { | |
| 1996/0531 |
| |
| 2002/0307 | pad = s->blocklen - pad; | |
| 1995/1218 | h++; | |
| 1995/1215 | } } | |
| 2002/0306/sys/src/9/port/devssl.c:780,794 – 2002/0307/sys/src/9/port/devssl.c:799,813 | ||
| 1995/1215 | rv += m; if(m != n){ nb = allocb(m + h + pad); | |
| 1996/0531 |
| |
| 2002/0307 | memmove(nb->wp + h, b->rp, m); | |
| 1995/1215 | nb->wp += m + h; | |
| 1996/0531 |
| |
| 2002/0307 | b->rp += m; | |
| 1995/1215 | } else { | |
| 1995/1218 | /* add header space */ | |
| 1996/0531 |
| |
| 2002/0307 | nb = padblock(b, h); b = 0; | |
| 1995/1215 | } | |
| 1996/0531 |
| |
| 2002/0307 | m += s->diglen; | |
| 1995/1215 | /* SSL style count */ if(pad){ | |
| 2002/0306/sys/src/9/port/devssl.c:809,836 – 2002/0307/sys/src/9/port/devssl.c:828,854 | ||
| 1995/1217 | offset = 2; } | |
| 1995/1213 | ||
| 1996/1029 |
| |
| 2002/0307 | switch(s->state){ | |
| 1996/1029 | case Sencrypting: | |
| 1996/0531 |
| |
| 2002/0307 | nb = encryptb(s, nb, offset); | |
| 1996/1029 | break; case Sdigesting: | |
| 1996/0531 |
| |
| 2002/0307 | nb = digestb(s, nb, offset); | |
| 1996/1029 | break; | |
| 1997/0618 | case Sdigenc: | |
| 2002/0307 | nb = digestb(s, nb, offset); nb = encryptb(s, nb, offset); | |
| 1997/0618 | break; | |
| 1996/1029 | } | |
| 1995/1213 | ||
| 1997/0618 |
| |
| 2002/0307 | s->out.mid++; | |
| 1997/0618 | ||
| 2001/0527 | m = BLEN(nb); | |
| 1997/0327 |
| |
| 2001/0527 |
| |
| 2002/0307 | devtab[s->c->type]->bwrite(s->c, nb, s->c->offset); s->c->offset += m; | |
| 1995/1215 | } | |
| 1996/0531 |
| |
| 1995/1215 |
| |
| 2002/0307 | poperror(); | |
| 1995/1215 | return rv; | |
| 1996/0223 | } | |
| 2002/0306/sys/src/9/port/devssl.c:1033,1096 – 2002/0307/sys/src/9/port/devssl.c:1051,1123 | ||
| 1997/0618 | } | |
| 1997/0327 | static long | |
| 1998/0319 |
| |
| 2002/0307 | sslwrite(Chan *c, void *a, long n, vlong) | |
| 1996/0223 | { | |
| 1996/1029 |
| |
| 1996/0531 |
| |
| 2002/0307 | Dstate * volatile s; Block * volatile b; | |
| 1996/1029 | int m, t; | |
| 1999/0804 | char *p, *np, *e, buf[128]; uchar *x; | |
| 1998/0319 |
| |
| 1996/0223 | ||
| 1996/1029 |
| |
| 2002/0307 | s = dstate[CONV(c->qid)]; if(s == 0) | |
| 1996/1029 | panic("sslwrite"); | |
| 1996/0223 | ||
| 1996/1029 | t = TYPE(c->qid); if(t == Qdata){ | |
| 2002/0307 | if(s->state == Sincomplete) | |
| 1996/1029 | error(Ebadusefd); | |
| 1996/0223 | ||
| 2002/0307 | /* lock should a write gets split over multiple records */ if(waserror()){ qunlock(&s->out.q); nexterror(); } qlock(&s->out.q); | |
| 1996/0223 | p = a; | |
| 1996/1029 | e = p + n; do { | |
| 1996/0223 | m = e - p; | |
| 1996/1029 |
| |
| 2002/0307 | if(m > s->max) m = s->max; | |
| 1998/0512 | ||
| 1996/0531 |
| |
| 2002/0307 | b = allocb(m); | |
| 1996/0223 | if(waserror()){ | |
| 1996/0531 |
| |
| 2002/0307 | freeb(b); | |
| 1996/0223 | nexterror(); } | |
| 1996/0531 |
| |
| 2002/0307 | memmove(b->wp, p, m); | |
| 1996/0223 | poperror(); | |
| 1996/0531 |
| |
| 2002/0307 | b->wp += m; | |
| 1998/0512 | ||
| 1996/0531 |
| |
| 2002/0307 | sslput(s, b); | |
| 1996/1029 | p += m; } while(p < e); | |
| 2002/0307 | poperror(); qunlock(&s->out.q); | |
| 1996/1029 | return n; } /* mutex with operations using what we're about to change */ if(waserror()){ | |
| 2002/0307 | qunlock(&s->in.ctlq); qunlock(&s->out.q); | |
| 1996/1029 | nexterror(); } | |
| 2002/0307 | qlock(&s->in.ctlq); qlock(&s->out.q); | |
| 1996/1029 | switch(t){ | |
| 1996/0223 | default: | |
| 1996/1029 | panic("sslwrite"); case Qsecretin: | |
| 2002/0307 | setsecret(&s->in, a, n); | |
| 1996/1029 | goto out; case Qsecretout: | |
| 2002/0307 | setsecret(&s->out, a, n); | |
| 1996/1029 | goto out; case Qctl: break; | |
| 2002/0306/sys/src/9/port/devssl.c:1108,1145 – 2002/0307/sys/src/9/port/devssl.c:1135,1172 | ||
| 1996/1029 | *p++ = 0; | |
| 1995/1213 | ||
| 1996/1029 | if(strcmp(buf, "fd") == 0){ | |
| 2002/0307 | s->c = buftochan(p); | |
| 1995/1213 | ||
| 1996/1029 | /* default is clear (msg delimiters only) */ | |
| 1997/0618 |
| |
| 2002/0307 | s->state = Sclear; s->blocklen = 1; s->diglen = 0; s->maxpad = s->max = (1<<15) - s->diglen - 1; s->in.mid = 0; s->out.mid = 0; | |
| 1996/1029 | } else if(strcmp(buf, "alg") == 0 && p != 0){ | |
| 2002/0307 | s->blocklen = 1; s->diglen = 0; | |
| 1995/1213 | ||
| 1996/1029 |
| |
| 2002/0307 | if(s->c == 0) | |
| 1996/1029 | error("must set fd before algorithm"); | |
| 1999/0527 |
| |
| 2002/0307 | s->state = Sclear; s->maxpad = s->max = (1<<15) - s->diglen - 1; | |
| 1996/1029 | if(strcmp(p, "clear") == 0){ goto out; | |
| 1995/1213 | } | |
| 1996/1029 |
| |
| 1997/0618 |
| |
| 2002/0307 | if(s->in.secret && s->out.secret == 0) setsecret(&s->out, s->in.secret, s->in.slen); if(s->out.secret && s->in.secret == 0) setsecret(&s->in, s->out.secret, s->out.slen); if(s->in.secret == 0 || s->out.secret == 0) | |
| 1997/0618 | error("algorithm but no secret"); | |
| 2002/0307 | s->hf = 0; s->encryptalg = Noencryption; s->blocklen = 1; | |
| 1997/0618 | for(;;){ np = strchr(p, ' '); | |
| 2002/0306/sys/src/9/port/devssl.c:1146,1153 – 2002/0307/sys/src/9/port/devssl.c:1173,1180 | ||
| 1997/0618 | if(np) *np++ = 0; | |
| 2002/0307 | if(parsehashalg(p, s) < 0) if(parseencryptalg(p, s) < 0) | |
| 1999/0804 | error("bad algorithm"); | |
| 1997/0618 | if(np == 0) | |
| 2002/0306/sys/src/9/port/devssl.c:1155,1188 – 2002/0307/sys/src/9/port/devssl.c:1182,1215 | ||
| 1997/0618 | p = np; } | |
| 2002/0307 | if(s->hf == 0 && s->encryptalg == Noencryption) | |
| 1999/0804 | error("bad algorithm"); | |
| 1995/1213 | ||
| 1996/1029 |
| |
| 2002/0307 | if(s->blocklen != 1){ s->max = (1<<15) - s->diglen - 1; s->max -= s->max % s->blocklen; s->maxpad = (1<<14) - s->diglen - 1; s->maxpad -= s->maxpad % s->blocklen; | |
| 1996/1029 | } else | |
| 2002/0307 | s->maxpad = s->max = (1<<15) - s->diglen - 1; | |
| 1999/0804 | } else if(strcmp(buf, "secretin") == 0 && p != 0) { m = (strlen(p)*3)/2; x = smalloc(m); | |
| 2002/0306 | t = dec64(x, m, p, strlen(p)); | |
| 2002/0307 | setsecret(&s->in, x, t); | |
| 1999/0804 | free(x); } else if(strcmp(buf, "secretout") == 0 && p != 0) { m = (strlen(p)*3)/2 + 1; x = smalloc(m); | |
| 2002/0306 | t = dec64(x, m, p, strlen(p)); | |
| 2002/0307 | setsecret(&s->out, x, t); | |
| 1999/0804 | free(x); | |
| 1996/1029 | } else error(Ebadarg); | |
| 1995/1213 | ||
| 1996/1029 | out: | |
| 2002/0307 | qunlock(&s->in.ctlq); qunlock(&s->out.q); | |
| 1996/1029 | poperror(); return n; | |
| 1998/0417 | } | |