| plan 9 kernel history: overview | file list | diff list |
1995/1215/port/devssl.c (diff list | history)
| 1995/1213/sys/src/9/port/devssl.c:159,182 – 1995/1215/sys/src/9/port/devssl.c:159,164 (short | long | prev | next) | ||
| 1995/1213 | error(Eperm); } | |
| 1995/1213/sys/src/9/port/devssl.c:335,396 – 1995/1215/sys/src/9/port/devssl.c:317,491 | ||
| 1995/1213 | return n; } | |
| 1995/1215 | /* * use SSL record format, add in count and digest or encrypt */ long sslbwrite(Chan *c, Block *b, ulong offset) | |
| 1995/1213 | { | |
| 1995/1215 | Dstate *s; | |
| 1995/1213 | Block *nb; | |
| 1995/1215 | int h, n, m, pad, rv; s = c->aux; if(s == 0 || s->state != Established) error(Ebadusefd); if(waserror()){ qunlock(&s->out); if(b) freeb(b); dighangup(s); nexterror(); } qlock(&s->out); rv = 0; while(b){ m = n = BLEN(b); h = s->diglen + 2; /* padded blocks are shorter than unpadded ones (strange) */ pad = 0; if(m > s->max){ m = s->max; } else if(s->blocklen != 1){ pad = m%s->blocklen; if(pad){ pad = s->blocklen - pad; if(m > s->maxpad){ pad = 0; m = s->maxpad; } } } rv += m; if(m != n){ nb = allocb(m + h + pad); memmove(nb->wp + h, m, b->rp); nb->wp += m + h; b->rp += m; } else { /* add header */ nb = padblock(b, h); nb->rp -= h; /* add pad */ if(pad) nb = padblock(nb, -pad); b = 0; } m += s->diglen; /* SSL style count */ if(pad){ memset(nb->wp, 0, pad); m += pad; nb->wp += pad; } else m |= 0x8000; np->rp[0] = (m>>8); np->rp[1] = m; | |
| 1995/1213 |
| |
| 1995/1215 | if(encryptalg) encryptb(s, nb); else digestb(s, nb); | |
| 1995/1213 |
| |
| 1995/1215 | (*devtab[s->c->type].bwrite)(s->c, nb, offset); | |
| 1995/1213 |
| |
| 1995/1215 | } qunlock(&s->out); poperror(); return rv; | |
| 1995/1213 | } | |
| 1995/1215 | Block* sslbread(Chan *c, long n, ulong offset) | |
| 1995/1213 | { | |
| 1995/1215 | Block *bp, **l; uchar count[2]; int len; int pad; | |
| 1995/1213 |
| |
| 1995/1215 | USED(offset); | |
| 1995/1213 |
| |
| 1995/1215 | s = c->aux; if(s == 0 || s->state != Established) error(Ebadusefd); if(waserror()){ qunlock(&s->in); dighangup(s); nexterror(); | |
| 1995/1213 | } | |
| 1995/1215 | qlock(&s->in); if(s->processed == 0){ | |
| 1995/1213 | ||
| 1995/1215 | /* read in the whole message */ s->processed = s->unprocessed; s->unprocessed =- 0; ensure(s, &s->processed, 2); consume(&s->processed, count, 2); if(count[0] & 0x80){ len = ((count[0] & 0x7f)<<8) | count[1]; pad = 0; } else { len = ((count[0] & 0x3f)<<8) | count[1]; ensure(s, &s->processed, 1); consume(&s->processed, count, 1); pad = count[0]; } ensure(s, &s->processed, len); /* put remainder on unprocessed */ i = 0; for(b = s->processed; b; b = b->next){ i = BLEN(b); if(i >= len) break; (*s->func)(b->rp, i, 0, &ss); len -= i; } if(b == 0) panic("digestbread"); if(i > len){ i -= len; s->unprocessed = allocb(i); memmove(s->unprocessed->wp, b->rp+len, i); s->unprocessed->wp += i; b->wp -= i; } if(s->encrypalg) decryptb(s, len); else checkdigestb(s, len); if(pad){ for(b = s->processed; b; b = b->next){ } b = s->processed; if(BLEN(b) > n){ b = allocb(n); memmove(b->wp, s->processed->rp, n); b->wp += n; s->processed->rp += n; } else s->processed = b->next; qunlock(&s->in); poperror(); return b; | |
| 1995/1213 | } | |
| 1995/1215 | Block* decryptb(Dstate *s, Block *b, int len) | |
| 1995/1213 | { ulong n, h; uchar *p, *ep; | |
| 1995/1213/sys/src/9/port/devssl.c:549,603 – 1995/1215/sys/src/9/port/devssl.c:644,707 | ||
| 1995/1213 | return b; } | |
| 1995/1215 | void digestb(Dstate *s, Block *b) | |
| 1995/1213 | { | |
| 1995/1215 | Block *nb; uchar *p; DigestState ss; uchar msgid[4]; ulong n, h; OneWay *w; | |
| 1995/1213 |
| |
| 1995/1215 | w = &s->out; | |
| 1995/1213 |
| |
| 1995/1215 | memset(&ss, 0, sizeof(ss)); h = s->diglen + 2; n = BLEN(b) - h; | |
| 1995/1213 |
| |
| 1995/1215 | /* hash secret + message */ (*s->hf)(w->secret, w->slen, 0, &ss); (*s->hf)(nb->rp + h, n, 0, &ss); | |
| 1995/1213 |
| |
| 1995/1215 | /* hash message id */ p = msgid; n = w->mid++; *p++ = n>>24; *p++ = n>>16; *p++ = n>>8; *p = n; (*s->func)(msgid, 4, nb->rp + 2, &ss); } | |
| 1995/1213 |
| |
| 1995/1215 | long encryptb(Dstate *s, Block *b) { ulong n, h; int j; uchar *p, *ep, *ip; DESstate *ds; | |
| 1995/1213 |
| |
| 1995/1215 | h = s->diglen + 2; | |
| 1995/1213 |
| |
| 1995/1215 | switch(s->encryptalg){ case DESEBC: ds = s->out.state; ep = b->rp + BLEN(b); for(p = b->rp + h; p < ep; p += 8) block_cipher(ds->expanded, p, 0); break; case DESCBC: ds = s->out.state; ep = b->rp + BLEN(b); for(p = b->rp + h; p < ep; p += 8) bCBCEncrypt(p, ds->ivec, ds->expanded, 8); break; } | |
| 1995/1213 | } | |
| 1995/1215 | /* get channel associated with an fd */ | |
| 1995/1213 | static Chan* buftochan(char *a, long n) { | |
| 1995/1213/sys/src/9/port/devssl.c:615,702 – 1995/1215/sys/src/9/port/devssl.c:719,741 | ||
| 1995/1213 | return c; } | |
| 1995/1215 | /* hand up a digest connection */ static void dighangup(Dstate *s) | |
| 1995/1213 | { | |
| 1995/1215 | Block *b; | |
| 1995/1213 |
| |
| 1995/1215 | qlock(&s->in); for(b = s->processed; b; b = s->processed){ s->processed = b->next; freeb(b); | |
| 1995/1213 | } | |
| 1995/1215 | if(s->unprocessed){ freeb(s->unprocessed); s->unprocessed = 0; | |
| 1995/1213 | } | |
| 1995/1215 | s->state = Closed; qunlock(&s->in); | |
| 1995/1213 | } /* | |