From 50dd353e3186e6a645f7091c38bf137978974f03 Mon Sep 17 00:00:00 2001 From: David du Colombier <0intro@gmail.com> Date: Sun, 3 Feb 2002 00:00:00 +0000 Subject: [PATCH] Plan 9 from Bell Labs 2002-02-03 --- port/devtls.c | 64 +++++++++++++++++++++++++++++++++++++++++++++----- port/portdat.h | 1 - 2 files changed, 58 insertions(+), 7 deletions(-) diff --git a/port/devtls.c b/port/devtls.c index d06065f4e793c8f36d199038a5f427a21c2752a1..b2bbac9d83af3e44606aa7fc426c9a4c150f8f74 100644 --- a/port/devtls.c +++ b/port/devtls.c @@ -45,6 +45,9 @@ enum { RHandshake, RApplication, + SSL2ClientHello = 1, + HSSL2ClientHello = 9, /* local convention; see tlshand.c */ + /* alerts */ ECloseNotify = 0, EUnexpectedMessage = 10, @@ -164,7 +167,7 @@ static TlsErrs tlserrs[] = { {EDecodeError, EIllegalParameter, EDecodeError, 1, "error decoding message"}, {EDecryptError, EIllegalParameter, EDecryptError, 1, "error decrypting message"}, {EExportRestriction, EHandshakeFailure, EExportRestriction, 1, "export restriction violated"}, - {EProtocolVersion, EIllegalParameter, EProtocolVersion, 0, "protocol version not supported"}, + {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"}, @@ -672,8 +675,7 @@ regurgitate(TlsRec *s, uchar *p, int n) } /* - * remove at most n bytes from the queue in a single block, if discard is set - * dump the remainder + * remove at most n bytes from the queue */ static Block* qgrab(Block **l, int n) @@ -742,9 +744,21 @@ tlsrecread(TlsRec *tr) ensure(tr, &tr->unprocessed, RecHdrLen); consume(&tr->unprocessed, header, RecHdrLen); nconsumed = RecHdrLen; - type = header[0]; - ver = get16(header+1); - len = get16(header+3); + + 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) - 5; + 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); + } if(ver != tr->version && (tr->verset || ver < MinProtoVersion || ver > MaxProtoVersion)) rcvError(tr, EProtocolVersion, "invalid version in record layer"); if(len > MaxRecLen || len < 0) @@ -869,6 +883,36 @@ tlsrecread(TlsRec *tr) } } 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); + 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"); @@ -2041,6 +2085,14 @@ put64(uchar *p, vlong x) put32(p+4, (u32int)x); } +static void +put24(uchar *p, int x) +{ + p[0] = x>>16; + p[1] = x>>8; + p[2] = x; +} + static void put16(uchar *p, int x) { diff --git a/port/portdat.h b/port/portdat.h index 47e5edf63c2356e94551ad3b9b00b65bacda9c9c..ae3c7f65dccd2e72aaa1214b442b8ffb7dc6dba1 100644 --- a/port/portdat.h +++ b/port/portdat.h @@ -416,7 +416,6 @@ struct Pgrp ulong pgrpid; QLock debug; /* single access via devproc.c */ RWlock ns; /* Namespace n read/one write lock */ - QLock nsh; Mhead *mnthash[MNTHASH]; };