diff e54b6c6cbd4d82d70ddb4932aeafb0b028cd71f5 uncommitted --- a//sys/src/9/port/devtls.c +++ b//sys/src/9/port/devtls.c @@ -1,5 +1,5 @@ /* - * devtls - record layer for transport layer security 1.2 and secure sockets layer 3.0 + * devtls - record layer for transport layer security 1.0-1.2 */ #include "u.h" #include "../port/lib.h" @@ -24,11 +24,10 @@ MaxMacLen = SHA2_256dlen, /* protocol versions we can accept */ - SSL3Version = 0x0300, TLS10Version = 0x0301, TLS11Version = 0x0302, TLS12Version = 0x0303, - MinProtoVersion = 0x0300, /* limits on version we accept */ + MinProtoVersion = 0x0301, /* limits on version we accept */ MaxProtoVersion = 0x03ff, /* connection states */ @@ -46,9 +45,6 @@ RHandshake, RApplication, - SSL2ClientHello = 1, - HSSL2ClientHello = 9, /* local convention; see tlshand.c */ - /* alerts */ ECloseNotify = 0, EUnexpectedMessage = 10, @@ -57,7 +53,6 @@ ERecordOverflow = 22, EDecompressionFailure = 30, EHandshakeFailure = 40, - ENoCertificate = 41, EBadCertificate = 42, EUnsupportedCertificate = 43, ECertificateRevoked = 44, @@ -89,7 +84,6 @@ int (*enc)(Secret*, uchar*, int); int (*dec)(Secret*, uchar*, int); - int (*unpad)(uchar*, int, int); DigestState* (*mac)(uchar*, ulong, uchar*, ulong, uchar*, DigestState*); int block; /* encryption block len, 0 if none */ @@ -125,12 +119,6 @@ int state; int debug; - /* - * function to genrate authenticated data blob for different - * protocol versions - */ - int (*packAAD)(u64int, uchar*, uchar*); - /* input side -- protected by in.io */ OneWay in; Block *processed; /* next bunch of application data */ @@ -153,37 +141,34 @@ struct TlsErrs{ int err; - int sslerr; - int tlserr; int fatal; char *msg; }; static TlsErrs tlserrs[] = { - {ECloseNotify, ECloseNotify, ECloseNotify, 0, "close notify"}, - {EUnexpectedMessage, EUnexpectedMessage, EUnexpectedMessage, 1, "unexpected message"}, - {EBadRecordMac, EBadRecordMac, EBadRecordMac, 1, "bad record mac"}, - {EDecryptionFailed, EIllegalParameter, EDecryptionFailed, 1, "decryption failed"}, - {ERecordOverflow, EIllegalParameter, ERecordOverflow, 1, "record too long"}, - {EDecompressionFailure, EDecompressionFailure, EDecompressionFailure, 1, "decompression failed"}, - {EHandshakeFailure, EHandshakeFailure, EHandshakeFailure, 1, "could not negotiate acceptable security parameters"}, - {ENoCertificate, ENoCertificate, ECertificateUnknown, 1, "no appropriate certificate available"}, - {EBadCertificate, EBadCertificate, EBadCertificate, 1, "corrupted or invalid certificate"}, - {EUnsupportedCertificate, EUnsupportedCertificate, EUnsupportedCertificate, 1, "unsupported certificate type"}, - {ECertificateRevoked, ECertificateRevoked, ECertificateRevoked, 1, "revoked certificate"}, - {ECertificateExpired, ECertificateExpired, ECertificateExpired, 1, "expired certificate"}, - {ECertificateUnknown, ECertificateUnknown, ECertificateUnknown, 1, "unacceptable certificate"}, - {EIllegalParameter, EIllegalParameter, EIllegalParameter, 1, "illegal parameter"}, - {EUnknownCa, EHandshakeFailure, EUnknownCa, 1, "unknown certificate authority"}, - {EAccessDenied, EHandshakeFailure, EAccessDenied, 1, "access denied"}, - {EDecodeError, EIllegalParameter, EDecodeError, 1, "error decoding message"}, - {EDecryptError, EIllegalParameter, EDecryptError, 1, "error decrypting message"}, - {EExportRestriction, EHandshakeFailure, EExportRestriction, 1, "export restriction violated"}, - {EProtocolVersion, EIllegalParameter, EProtocolVersion, 1, "protocol version not supported"}, - {EInsufficientSecurity, EHandshakeFailure, EInsufficientSecurity, 1, "stronger security routines required"}, - {EInternalError, EHandshakeFailure, EInternalError, 1, "internal error"}, - {EUserCanceled, ECloseNotify, EUserCanceled, 0, "handshake canceled by user"}, - {ENoRenegotiation, EUnexpectedMessage, ENoRenegotiation, 0, "no renegotiation"}, + {ECloseNotify, 0, "close notify"}, + {EUnexpectedMessage, 1, "unexpected message"}, + {EBadRecordMac, 1, "bad record mac"}, + {EDecryptionFailed, 1, "decryption failed"}, + {ERecordOverflow, 1, "record too long"}, + {EDecompressionFailure, 1, "decompression failed"}, + {EHandshakeFailure, 1, "could not negotiate acceptable security parameters"}, + {EBadCertificate, 1, "corrupted or invalid certificate"}, + {EUnsupportedCertificate, 1, "unsupported certificate type"}, + {ECertificateRevoked, 1, "revoked certificate"}, + {ECertificateExpired, 1, "expired certificate"}, + {ECertificateUnknown, 1, "unacceptable certificate"}, + {EIllegalParameter, 1, "illegal parameter"}, + {EUnknownCa, 1, "unknown certificate authority"}, + {EAccessDenied, 1, "access denied"}, + {EDecodeError, 1, "error decoding message"}, + {EDecryptError, 1, "error decrypting message"}, + {EExportRestriction, 1, "export restriction violated"}, + {EProtocolVersion, 1, "protocol version not supported"}, + {EInsufficientSecurity, 1, "stronger security routines required"}, + {EInternalError, 1, "internal error"}, + {EUserCanceled, 0, "handshake canceled by user"}, + {ENoRenegotiation, 0, "no renegotiation"}, }; enum @@ -227,11 +212,8 @@ static void alertHand(TlsRec*, char *); static TlsRec *newtls(Chan *c); static TlsRec *mktlsrec(void); -static DigestState*sslmac_md5(uchar *p, ulong len, uchar *key, ulong klen, uchar *digest, DigestState *s); -static DigestState*sslmac_sha1(uchar *p, ulong len, uchar *key, ulong klen, uchar *digest, DigestState *s); static DigestState*nomac(uchar *p, ulong len, uchar *key, ulong klen, uchar *digest, DigestState *s); -static int sslPackAAD(u64int, uchar*, uchar*); -static int tlsPackAAD(u64int, uchar*, uchar*); +static int packAAD(u64int, uchar*, uchar*); static void packMac(Secret*, uchar*, int, uchar*, int, uchar*); static void put64(uchar *p, u64int); static void put32(uchar *p, u32int); @@ -252,8 +234,7 @@ static int aesgcm_aead_enc(Secret *sec, uchar *aad, int aadlen, uchar *reciv, uchar *data, int len); static int aesgcm_aead_dec(Secret *sec, uchar *aad, int aadlen, uchar *reciv, uchar *data, int len); static int noenc(Secret *sec, uchar *buf, int n); -static int sslunpad(uchar *buf, int n, int block); -static int tlsunpad(uchar *buf, int n, int block); +static int unpad(uchar *buf, int n, int block); static void freeSec(Secret *sec); static char *tlsstate(int s); static void pdump(int, void*, char*); @@ -749,20 +730,10 @@ if(tr->debug)pprint("consumed %d header\n", RecHdrLen); nconsumed = RecHdrLen; - if((tr->handin == 0) && (header[0] & 0x80)){ - /* Cope with an SSL3 ClientHello expressed in SSL2 record format. - This is sent by some clients that we must interoperate - with, such as Java's JSSE and Microsoft's Internet Explorer. */ - len = (get16(header) & ~0x8000) - 3; - type = header[2]; - ver = get16(header + 3); - if(type != SSL2ClientHello || len < 22) - rcvError(tr, EProtocolVersion, "invalid initial SSL2-like message"); - }else{ /* normal SSL3 record format */ - type = header[0]; - ver = get16(header+1); - len = get16(header+3); - } + type = header[0]; + ver = get16(header+1); + len = get16(header+3); + if(ver != tr->version && (tr->verset || ver < MinProtoVersion || ver > MaxProtoVersion)) rcvError(tr, EProtocolVersion, "devtls expected ver=%x%s, saw (len=%d) type=%x ver=%x '%.12s'", tr->version, tr->verset?"/set":"", len, type, ver, (char*)header); @@ -823,7 +794,7 @@ /* update length */ put16(header+3, len); - aadlen = (*tr->packAAD)(in->seq++, header, aad); + aadlen = packAAD(in->seq++, header, aad); if(sec->aead_dec != nil) { len = (*sec->aead_dec)(sec, aad, aadlen, p - ivlen, p, unpad_len); if(len < 0) @@ -916,42 +887,12 @@ dechandq(tr); }else{ unlock(&tr->hqlock); - if(tr->verset && tr->version != SSL3Version && !waserror()){ + if(tr->verset && !waserror()){ sendAlert(tr, ENoRenegotiation); poperror(); } } break; - case SSL2ClientHello: - lock(&tr->hqlock); - if(tr->handq != nil){ - tr->hqref++; - unlock(&tr->hqlock); - if(waserror()){ - dechandq(tr); - nexterror(); - } - /* Pass the SSL2 format data, so that the handshake code can compute - the correct checksums. HSSL2ClientHello = HandshakeType 9 is - unused in RFC2246. */ - b = padblock(b, 8); - b->rp[0] = RHandshake; - b->rp[1] = HSSL2ClientHello; - put24(&b->rp[2], len+3); - b->rp[5] = SSL2ClientHello; - put16(&b->rp[6], ver); - qbwrite(tr->handq, b); - b = nil; - poperror(); - dechandq(tr); - }else{ - unlock(&tr->hqlock); - if(tr->verset && tr->version != SSL3Version && !waserror()){ - sendAlert(tr, ENoRenegotiation); - poperror(); - } - } - break; case RApplication: if(!tr->opened) rcvError(tr, EUnexpectedMessage, "application message received before handshake completed"); @@ -1314,7 +1255,7 @@ put16(p+3, n); if(sec != nil){ - aadlen = (*tr->packAAD)(out->seq++, p, aad); + aadlen = packAAD(out->seq++, p, aad); if(sec->aead_enc != nil) n = (*sec->aead_enc)(sec, aad, aadlen, p + RecHdrLen, p + RecHdrLen + ivlen, n) + ivlen; else { @@ -1390,42 +1331,34 @@ { char *name; int maclen; - void (*initkey)(Hashalg *, int, Secret *, uchar*); + void (*initkey)(Hashalg *, Secret *, uchar*); }; static void -initmd5key(Hashalg *ha, int version, Secret *s, uchar *p) +initmd5key(Hashalg *ha, Secret *s, uchar *p) { s->maclen = ha->maclen; - if(version == SSL3Version) - s->mac = sslmac_md5; - else - s->mac = hmac_md5; + s->mac = hmac_md5; memmove(s->mackey, p, ha->maclen); } static void -initclearmac(Hashalg *, int, Secret *s, uchar *) +initclearmac(Hashalg *, Secret *s, uchar *) { s->mac = nomac; } static void -initsha1key(Hashalg *ha, int version, Secret *s, uchar *p) +initsha1key(Hashalg *ha, Secret *s, uchar *p) { s->maclen = ha->maclen; - if(version == SSL3Version) - s->mac = sslmac_sha1; - else - s->mac = hmac_sha1; + s->mac = hmac_sha1; memmove(s->mackey, p, ha->maclen); } static void -initsha2_256key(Hashalg *ha, int version, Secret *s, uchar *p) +initsha2_256key(Hashalg *ha, Secret *s, uchar *p) { - if(version == SSL3Version) - error("sha256 cannot be used with SSL"); s->maclen = ha->maclen; s->mac = hmac_sha2_256; memmove(s->mackey, p, ha->maclen); @@ -1641,10 +1574,6 @@ m = strtol(cb->f[1], nil, 0); if(m < MinProtoVersion || m > MaxProtoVersion) error("unsupported version"); - if(m == SSL3Version) - tr->packAAD = sslPackAAD; - else - tr->packAAD = tlsPackAAD; tr->verset = 1; tr->version = m; }else if(strcmp(cb->f[0], "secret") == 0){ @@ -1685,8 +1614,8 @@ if(!ha->initkey || !ea->initkey) error("misimplemented secret algorithm"); - (*ha->initkey)(ha, tr->version, tos, &x[0]); - (*ha->initkey)(ha, tr->version, toc, &x[ha->maclen]); + (*ha->initkey)(ha, tos, &x[0]); + (*ha->initkey)(ha, toc, &x[ha->maclen]); (*ea->initkey)(ea, tos, &x[2 * ha->maclen], &x[2 * ha->maclen + 2 * ea->keylen]); (*ea->initkey)(ea, toc, &x[2 * ha->maclen + ea->keylen], &x[2 * ha->maclen + 2 * ea->keylen + ea->ivlen]); @@ -1701,13 +1630,6 @@ tr->in.new = toc; tr->out.new = tos; } - if(tr->version == SSL3Version){ - toc->unpad = sslunpad; - tos->unpad = sslunpad; - }else{ - toc->unpad = tlsunpad; - tos->unpad = tlsunpad; - } toc->encalg = ea->name; toc->hashalg = ha->name; tos->encalg = ea->name; @@ -1879,17 +1801,12 @@ if(tr->debug)pprint("sendAlert %d\n", err); fatal = 1; msg = "tls unknown alert"; - for(i=0; i < nelem(tlserrs); i++) { - if(tlserrs[i].err == err) { + for(i=0; i < nelem(tlserrs); i++) + if(tlserrs[i].err == err){ msg = tlserrs[i].msg; - if(tr->version == SSL3Version) - err = tlserrs[i].sslerr; - else - err = tlserrs[i].tlserr; fatal = tlserrs[i].fatal; break; } - } if(!waserror()){ b = allocb(2); @@ -2061,7 +1978,7 @@ } static int -tlsunpad(uchar *buf, int n, int block) +unpad(uchar *buf, int n, int block) { int pad, nn; @@ -2076,18 +1993,6 @@ } static int -sslunpad(uchar *buf, int n, int block) -{ - int pad, nn; - - pad = buf[n - 1]; - nn = n - 1 - pad; - if(nn <= 0 || n % block) - return -1; - return nn; -} - -static int blockpad(uchar *buf, int n, int block) { int pad, nn; @@ -2112,7 +2017,7 @@ des3dec(Secret *sec, uchar *buf, int n) { des3CBCdecrypt(buf, n, sec->enckey); - return (*sec->unpad)(buf, n, 8); + return unpad(buf, n, 8); } static int @@ -2127,7 +2032,7 @@ aesdec(Secret *sec, uchar *buf, int n) { aesCBCdecrypt(buf, n, sec->enckey); - return (*sec->unpad)(buf, n, 16); + return unpad(buf, n, 16); } static void @@ -2213,71 +2118,8 @@ return nil; } -/* - * sslmac: mac calculations for ssl 3.0 only; tls 1.0 uses the standard hmac. - */ -static DigestState* -sslmac_x(uchar *p, ulong len, uchar *key, ulong klen, uchar *digest, DigestState *s, - DigestState*(*x)(uchar*, ulong, uchar*, DigestState*), int xlen, int padlen) -{ - int i; - uchar pad[48], innerdigest[20]; - - if(xlen > sizeof(innerdigest) - || padlen > sizeof(pad)) - return nil; - - if(klen>64) - return nil; - - /* first time through */ - if(s == nil){ - for(i=0; i