9front - general discussion about 9front
 help / color / mirror / Atom feed
From: kemal <kemalinanc8@gmail.com>
To: 9front@9front.org
Subject: Re: [9front] intent to delete: devssl, cpu, oexportfs, import
Date: Sat, 23 Oct 2021 23:13:28 +0300	[thread overview]
Message-ID: <CABO6shdSD2WOr0VoG_dNP02uBrCjwqUaH32=NYKQG5AngtLp9w@mail.gmail.com> (raw)
In-Reply-To: <3C4C4D2C08BED22ADA0AB655C658BECA@eigenstate.org>

[-- Attachment #1: Type: text/plain, Size: 1077 bytes --]

> but I think this can go in before we get rid of
> devtls; cpu bypasses the handshake, so as long as
> we keep devtls it should keep working regardless of
> libsec.

getting rid of devtls o_O? i think you meant devssl.

also, while reviewing my diff more, i found 2 more flaws
in it:

1. i shouldn't have scrapped the ssl2 handshake support.
i learned that some old versions of java that has tls 1.0
still sends the clienthello in the ssl2 format.

2. if initial clienthello has 0x0300 as its record layer
version, devtls will reject it with this diff. this is not good,
clients may put the minimum version they support
in the record layer version, for compatibility with
old servers. fix this up.

3 more changes, that is not related with the diff:

1. don't reject protocol versions that is higher than 0x03ff.
this behavior is useless.

2. devtls shouldn't accept versions higher
than 0x0303 in the fd and version commands.

3. in tlshand, use the minimum protocol version
we support for the record layer version for compatibility
until we manage to negotiate the version.

[-- Attachment #2: diff.txt --]
[-- Type: text/plain, Size: 30282 bytes --]

diff 5b5f69513adcb9939e4ebd93bf8adfbfdc08fcf1 uncommitted
--- a//sys/man/2/pushtls
+++ b//sys/man/2/pushtls
@@ -1,6 +1,6 @@
 .TH PUSHTLS 2
 .SH NAME
-pushtls, tlsClient, tlsServer, initThumbprints, freeThumbprints, okThumbprint, okCertificate, readcert, readcertchain \- attach TLS1 or SSL3 encryption to a communication channel
+pushtls, tlsClient, tlsServer, initThumbprints, freeThumbprints, okThumbprint, okCertificate, readcert, readcertchain \- attach TLS encryption to a communication channel
 .SH SYNOPSIS
 .B #include <u.h>
 .br
@@ -45,8 +45,6 @@
 and a handshake protocol,
 doing initial authentication and secret creation at
 user level and then starting a data channel in the record protocol.
-TLS is nearly the same as SSL 3.0, and the software should interoperate
-with implementations of either standard.
 .PP
 To use just the record layer, as described in
 .IR tls (3),
--- a//sys/man/3/tls
+++ b//sys/man/3/tls
@@ -1,6 +1,6 @@
 .TH TLS 3 
 .SH NAME
-tls \- TLS and SSL3 record layer
+tls \- TLS record layer
 .SH SYNOPSIS
 .nf
 .B bind -a #a /net
@@ -16,10 +16,9 @@
 .BI /net/tls/ n /status
 .fi
 .SH DESCRIPTION
-The TLS device implements the record layer protocols
-of Transport Layer Security version 1.0-1.2 and Secure Sockets Layer version 3.0.
-It does not implement the handshake protocols, which are responsible for
-mutual authentication and key exchange.
+The TLS device implements the record layer protocols of Transport Layer Security
+version 1.0-1.2. It does not implement the handshake protocols, which are responsible
+for mutual authentication and key exchange.
 The
 .I tls
 device can be thought of as filters providing optional encryption and anti-tampering.
@@ -53,13 +52,11 @@
 .I vers
 format records, but incoming messages of either version are accepted.
 Valid versions are
-.B 0x300
-for SSLv3.0 and
 .BR 0x301 ,
 .B 0x302
 and
 .B 0x303
-for TLSv1.0 (which could be known as SSLv3.01), TLSv1.1 and TLSv1.2.
+for TLSv1.0, TLSv1.1 and TLSv1.2.
 This command must be issued before any other command
 and before reading or writing any messages;
 it may only be executed once.
@@ -120,10 +117,9 @@
 .TP
 .BI alert \ alertno
 Send an alert message.
-.I Alertno
-may be a valid alert code for either SSLv3.0 or TLS,
-and is mapped to an appropriate code for the protocol in use.
-If it is a fatal alert, the filter is set into an error state.
+If
+.I alertno
+is a fatal alert, the filter is set into an error state.
 .PP
 Application messages and handshake messages are communicated using
 .I data
--- 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,12 +24,11 @@
 	MaxMacLen	= SHA2_256dlen,
 
 	/* protocol versions we can accept */
-	SSL3Version	= 0x0300,
 	TLS10Version	= 0x0301,
 	TLS11Version	= 0x0302,
 	TLS12Version	= 0x0303,
-	MinProtoVersion	= 0x0300,	/* limits on version we accept */
-	MaxProtoVersion	= 0x03ff,
+	MinProtoVersion	= TLS10Version,	/* limits on version we accept */
+	MaxProtoVersion	= TLS12Version,
 
 	/* connection states */
 	SHandshake	= 1 << 0,	/* doing handshake */
@@ -57,7 +56,6 @@
 	ERecordOverflow 		= 22,
 	EDecompressionFailure 	= 30,
 	EHandshakeFailure 		= 40,
-	ENoCertificate 			= 41,
 	EBadCertificate 		= 42,
 	EUnsupportedCertificate 	= 43,
 	ECertificateRevoked 		= 44,
@@ -89,7 +87,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 +122,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 +144,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 +215,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 +237,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*);
@@ -750,7 +734,7 @@
 	nconsumed = RecHdrLen;
 
 	if((tr->handin == 0) && (header[0] & 0x80)){
-		/* Cope with an SSL3 ClientHello expressed in SSL2 record format.
+		/* Cope with a TLS 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;
@@ -758,12 +742,12 @@
 		ver = get16(header + 3);
 		if(type != SSL2ClientHello || len < 22)
 			rcvError(tr, EProtocolVersion, "invalid initial SSL2-like message");
-	}else{  /* normal SSL3 record format */
+	}else{  /* normal TLS record format */
 		type = header[0];
 		ver = get16(header+1);
 		len = get16(header+3);
 	}
-	if(ver != tr->version && (tr->verset || ver < MinProtoVersion || ver > MaxProtoVersion))
+	if(ver != tr->version && (tr->verset || ver < 0x0300))
 		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);
 	if(len > MaxCipherRecLen || len < 0)
@@ -823,7 +807,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,7 +900,7 @@
 			dechandq(tr);
 		}else{
 			unlock(&tr->hqlock);
-			if(tr->verset && tr->version != SSL3Version && !waserror()){
+			if(tr->verset && !waserror()){
 				sendAlert(tr, ENoRenegotiation);
 				poperror();
 			}
@@ -933,7 +917,7 @@
 			}
 			/* Pass the SSL2 format data, so that the handshake code can compute
 				the correct checksums.  HSSL2ClientHello = HandshakeType 9 is
-				unused in RFC2246. */
+				unused in RFC5246. */
 			b = padblock(b, 8);
 			b->rp[0] = RHandshake;
 			b->rp[1] = HSSL2ClientHello;
@@ -946,7 +930,7 @@
 			dechandq(tr);
 		}else{
 			unlock(&tr->hqlock);
-			if(tr->verset && tr->version != SSL3Version && !waserror()){
+			if(tr->verset && !waserror()){
 				sendAlert(tr, ENoRenegotiation);
 				poperror();
 			}
@@ -1314,7 +1298,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 +1374,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 +1617,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 +1657,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 +1673,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 +1844,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 +2021,7 @@
 }
 
 static int
-tlsunpad(uchar *buf, int n, int block)
+unpad(uchar *buf, int n, int block)
 {
 	int pad, nn;
 
@@ -2076,18 +2036,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 +2060,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 +2075,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 +2161,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<padlen; i++)
-			pad[i] = 0x36;
-		s = (*x)(key, klen, nil, nil);
-		s = (*x)(pad, padlen, nil, s);
-		if(s == nil)
-			return nil;
-	}
-
-	s = (*x)(p, len, nil, s);
-	if(digest == nil)
-		return s;
-
-	/* last time through */
-	for(i=0; i<padlen; i++)
-		pad[i] = 0x5c;
-	(*x)(nil, 0, innerdigest, s);
-	s = (*x)(key, klen, nil, nil);
-	s = (*x)(pad, padlen, nil, s);
-	(*x)(innerdigest, xlen, digest, s);
-	return nil;
-}
-
-static DigestState*
-sslmac_sha1(uchar *p, ulong len, uchar *key, ulong klen, uchar *digest, DigestState *s)
-{
-	return sslmac_x(p, len, key, klen, digest, s, sha1, SHA1dlen, 40);
-}
-
-static DigestState*
-sslmac_md5(uchar *p, ulong len, uchar *key, ulong klen, uchar *digest, DigestState *s)
-{
-	return sslmac_x(p, len, key, klen, digest, s, md5, MD5dlen, 48);
-}
-
 static int
-sslPackAAD(u64int seq, uchar *hdr, uchar *aad)
-{
-	put64(aad, seq);
-	aad[8] = hdr[0];
-	aad[9] = hdr[3];
-	aad[10] = hdr[4];
-	return 11;
-}
-
-static int
-tlsPackAAD(u64int seq, uchar *hdr, uchar *aad)
+packAAD(u64int seq, uchar *hdr, uchar *aad)
 {
 	put64(aad, seq);
 	aad[8] = hdr[0];
--- a//sys/src/libsec/port/tlshand.c
+++ b//sys/src/libsec/port/tlshand.c
@@ -8,14 +8,13 @@
 //		client/server - main handshake protocol definition
 //		message functions - formating handshake messages
 //		cipher choices - catalog of digest and encrypt algorithms
-//		security functions - PKCS#1, sslHMAC, session keygen
+//		security functions - PKCS#1, session keygen
 //		general utility functions - malloc, serialization
-// The handshake protocol builds on the TLS/SSL3 record layer protocol,
-// which is implemented in kernel device #a.  See also /lib/rfc/rfc2246.
+// The handshake protocol builds on the TLS record layer protocol,
+// which is implemented in kernel device #a.  See also /lib/rfc/rfc5246.
 
 enum {
-	TLSFinishedLen = 12,
-	SSL3FinishedLen = MD5dlen+SHA1dlen,
+	FinishedLen = 12,
 	MaxKeyData = 160,	// amount of secret we may need
 	MAXdlen = SHA2_512dlen,
 	RandomSize = 32,
@@ -47,11 +46,6 @@
 	void (*init)(mpint *p, mpint *a, mpint *b, mpint *x, mpint *y, mpint *n, mpint *h);
 } Namedcurve;
 
-typedef struct Finished{
-	uchar verify[SSL3FinishedLen];
-	int n;
-} Finished;
-
 typedef struct HandshakeHash {
 	MD5state	md5;
 	SHAstate	sha1;
@@ -81,7 +75,6 @@
 	// byte generation and handshake checksum
 	void (*prf)(uchar*, int, uchar*, int, char*, uchar*, int);
 	void (*setFinished)(TlsSec*, HandshakeHash, uchar*, int);
-	int nfin;
 };
 
 typedef struct TlsConnection{
@@ -99,7 +92,7 @@
 
 	// for finished messages
 	HandshakeHash	handhash;
-	Finished	finished;
+	uchar		finished[FinishedLen];
 
 	uchar *sendp;
 	uchar buf[1<<16];
@@ -152,19 +145,17 @@
 			int sigalg;
 			Bytes *signature;
 		} certificateVerify;		
-		Finished finished;
+		uchar finished[FinishedLen];
 	} u;
 } Msg;
 
 
 enum {
-	SSL3Version	= 0x0300,
 	TLS10Version	= 0x0301,
 	TLS11Version	= 0x0302,
 	TLS12Version	= 0x0303,
 	ProtocolVersion	= TLS12Version,	// maximum version we speak
-	MinProtoVersion	= 0x0300,	// limits on version we accept
-	MaxProtoVersion	= 0x03ff,
+	MinProtoVersion	= TLS10Version,	// limits on version we accept
 };
 
 // handshake type
@@ -192,7 +183,6 @@
 	ERecordOverflow = 22,
 	EDecompressionFailure = 30,
 	EHandshakeFailure = 40,
-	ENoCertificate = 41,
 	EBadCertificate = 42,
 	EUnsupportedCertificate = 43,
 	ECertificateRevoked = 44,
@@ -367,7 +357,6 @@
 #pragma	varargck argpos	tlsError 3
 static int setVersion(TlsConnection *c, int version);
 static int setSecrets(TlsConnection *c, int isclient);
-static int finishedMatch(TlsConnection *c, Finished *f);
 static void tlsConnectionFree(TlsConnection *c);
 
 static int isDHE(int tlsid);
@@ -394,7 +383,6 @@
 static Bytes*	tlsSecDHEc(TlsSec *sec, Bytes *p, Bytes *g, Bytes *Ys);
 static Bytes*	tlsSecECDHEc(TlsSec *sec, int curve, Bytes *Ys);
 static void	tlsSecVers(TlsSec *sec, int v);
-static int	tlsSecFinished(TlsSec *sec, HandshakeHash hsh, uchar *fin, int nfin, int isclient);
 static void	setMasterSecret(TlsSec *sec, Bytes *pm);
 static int	digestDHparams(TlsSec *sec, Bytes *par, uchar digest[MAXdlen], int sigalg);
 static char*	verifyDHparams(TlsSec *sec, Bytes *par, Bytes *cert, Bytes *sig, int sigalg);
@@ -451,7 +439,7 @@
 		return -1;
 	}
 	data = -1;
-	fprint(ctl, "fd %d 0x%x", fd, ProtocolVersion);
+	fprint(ctl, "fd %d 0x%x", fd, MinProtoVersion);
 	tls = tlsServer2(ctl, hand,
 		conn->cert, conn->certlen,
 		conn->pskID, conn->psk, conn->psklen,
@@ -511,28 +499,26 @@
 	}
 
 	// Elliptic Curves (also called Supported Groups)
-	if(ProtocolVersion >= TLS10Version){
-		m = p - b;
-		b = erealloc(b, m + 2+2+2+nelem(namedcurves)*2 + 2+2+1+nelem(pointformats));
-		p = b + m;
+	m = p - b;
+	b = erealloc(b, m + 2+2+2+nelem(namedcurves)*2 + 2+2+1+nelem(pointformats));
+	p = b + m;
 
-		n = nelem(namedcurves);
-		put16(p, Extec), p += 2;	/* Type: elliptic_curves / supported_groups */
-		put16(p, (n+1)*2), p += 2;	/* Length */
-		put16(p, n*2), p += 2;		/* Elliptic Curves Length */
-		for(i=0; i < n; i++){		/* Elliptic Curves */
-			put16(p, namedcurves[i].tlsid);
-			p += 2;
-		}
-
-		n = nelem(pointformats);
-		put16(p, Extecp), p += 2;	/* Type: ec_point_formats */
-		put16(p, n+1), p += 2;		/* Length */
-		*p++ = n;			/* EC point formats Length */
-		for(i=0; i < n; i++)		/* EC point formats */
-			*p++ = pointformats[i];
+	n = nelem(namedcurves);
+	put16(p, Extec), p += 2;	/* Type: elliptic_curves / supported_groups */
+	put16(p, (n+1)*2), p += 2;	/* Length */
+	put16(p, n*2), p += 2;		/* Elliptic Curves Length */
+	for(i=0; i < n; i++){		/* Elliptic Curves */
+		put16(p, namedcurves[i].tlsid);
+		p += 2;
 	}
 
+	n = nelem(pointformats);
+	put16(p, Extecp), p += 2;	/* Type: ec_point_formats */
+	put16(p, n+1), p += 2;		/* Length */
+	*p++ = n;			/* EC point formats Length */
+	for(i=0; i < n; i++)		/* EC point formats */
+		*p++ = pointformats[i];
+
 	// signature algorithms
 	if(ProtocolVersion >= TLS12Version){
 		n = nelem(sigalgs);
@@ -591,7 +577,7 @@
 		close(ctl);
 		return -1;
 	}
-	fprint(ctl, "fd %d 0x%x", fd, ProtocolVersion);
+	fprint(ctl, "fd %d 0x%x", fd, MinProtoVersion);
 	ext = tlsClientExtensions(conn, &n);
 	tls = tlsClient2(ctl, hand,
 		conn->cert, conn->certlen, 
@@ -849,10 +835,7 @@
 	}
 
 	/* no CertificateVerify; skip to Finished */
-	if(tlsSecFinished(c->sec, c->handhash, c->finished.verify, c->finished.n, 1) < 0){
-		tlsError(c, EInternalError, "can't set finished: %r");
-		goto Err;
-	}
+	(*c->sec->setFinished)(c->sec, c->handhash, c->finished, 1);
 	if(!msgRecv(c, &m))
 		goto Err;
 	if(m.tag != HFinished) {
@@ -859,7 +842,7 @@
 		tlsError(c, EUnexpectedMessage, "expected a finished");
 		goto Err;
 	}
-	if(!finishedMatch(c, &m.u.finished)) {
+	if(tsmemcmp(c->finished, m.u.finished, FinishedLen) != 0) {
 		tlsError(c, EHandshakeFailure, "finished verification failed");
 		goto Err;
 	}
@@ -871,12 +854,9 @@
 		goto Err;
 	}
 
-	if(tlsSecFinished(c->sec, c->handhash, c->finished.verify, c->finished.n, 0) < 0){
-		tlsError(c, EInternalError, "can't set finished: %r");
-		goto Err;
-	}
+	(*c->sec->setFinished)(c->sec, c->handhash, c->finished, 0);
 	m.tag = HFinished;
-	m.u.finished = c->finished;
+	memmove(m.u.finished, c->finished, FinishedLen);
 	if(!msgSend(c, &m, AFlush))
 		goto Err;
 	if(trace)
@@ -1220,21 +1200,15 @@
 
 	// Cipherchange must occur immediately before Finished to avoid
 	// potential hole;  see section 4.3 of Wagner Schneier 1996.
-	if(tlsSecFinished(c->sec, c->handhash, c->finished.verify, c->finished.n, 1) < 0){
-		tlsError(c, EInternalError, "can't set finished 1: %r");
-		goto Err;
-	}
+	(*c->sec->setFinished)(c->sec, c->handhash, c->finished, 1);
 	m.tag = HFinished;
-	m.u.finished = c->finished;
+	memmove(m.u.finished, c->finished, FinishedLen);
 	if(!msgSend(c, &m, AFlush)) {
 		tlsError(c, EInternalError, "can't flush after client Finished: %r");
 		goto Err;
 	}
 
-	if(tlsSecFinished(c->sec, c->handhash, c->finished.verify, c->finished.n, 0) < 0){
-		tlsError(c, EInternalError, "can't set finished 0: %r");
-		goto Err;
-	}
+	(*c->sec->setFinished)(c->sec, c->handhash, c->finished, 0);
 	if(!msgRecv(c, &m)) {
 		tlsError(c, EInternalError, "can't read server Finished: %r");
 		goto Err;
@@ -1244,7 +1218,7 @@
 		goto Err;
 	}
 
-	if(!finishedMatch(c, &m.u.finished)) {
+	if(tsmemcmp(c->finished, m.u.finished, FinishedLen) != 0) {
 		tlsError(c, EHandshakeFailure, "finished verification failed");
 		goto Err;
 	}
@@ -1418,16 +1392,16 @@
 			goto Overflow;
 		if(isECDHE(c->cipher))
 			*p++ = n;
-		else if(isDHE(c->cipher) || c->version != SSL3Version)
+		else
 			put16(p, n), p += 2;
 		memmove(p, m->u.clientKeyExchange.key->data, n);
 		p += n;
 		break;
 	case HFinished:
-		if(p+m->u.finished.n > e)
+		if(p+FinishedLen > e)
 			goto Overflow;
-		memmove(p, m->u.finished.verify, m->u.finished.n);
-		p += m->u.finished.n;
+		memmove(p, m->u.finished, FinishedLen);
+		p += FinishedLen;
 		break;
 	}
 
@@ -1496,7 +1470,7 @@
 	}
 
 	if(type == HSSL2ClientHello){
-		/* Cope with an SSL3 ClientHello expressed in SSL2 record format.
+		/* Cope with an TLS 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. */
 		int nsid, nrandom, nciph;
@@ -1519,7 +1493,7 @@
 		if(nsid != 0 	/* no sid's, since shouldn't restart using ssl2 header */
 		|| nrandom < 16 || nn % 3 || n - nrandom < nn)
 			goto Err;
-		/* ignore ssl2 ciphers and look for {0x00, ssl3 cipher} */
+		/* ignore ssl2 ciphers and look for {0x00, tls cipher} */
 		nciph = 0;
 		for(i = 0; i < nn; i += 3)
 			if(p[i] == 0)
@@ -1790,10 +1764,8 @@
 			goto Short;
 		if(isECDHE(c->cipher))
 			nn = *p++, n--;
-		else if(isDHE(c->cipher) || c->version != SSL3Version)
-			nn = get16(p), p += 2, n -= 2;
 		else
-			nn = n;
+			nn = get16(p), p += 2, n -= 2;
 		if(n < nn)
 			goto Short;
 		m->u.clientKeyExchange.key = makebytes(p, nn);
@@ -1800,11 +1772,10 @@
 		n -= nn;
 		break;
 	case HFinished:
-		m->u.finished.n = c->finished.n;
-		if(n < m->u.finished.n)
+		if(n < FinishedLen)
 			goto Short;
-		memmove(m->u.finished.verify, p, m->u.finished.n);
-		n -= m->u.finished.n;
+		memmove(m->u.finished, p, FinishedLen);
+		n -= FinishedLen;
 		break;
 	}
 
@@ -2000,8 +1971,8 @@
 		break;
 	case HFinished:
 		bs = seprint(bs, be, "HFinished\n");
-		for(i=0; i<m->u.finished.n; i++)
-			bs = seprint(bs, be, "%.2x", m->u.finished.verify[i]);
+		for(i=0; i<FinishedLen; i++)
+			bs = seprint(bs, be, "%.2x", m->u.finished[i]);
 		bs = seprint(bs, be, "\n");
 		break;
 	}
@@ -2032,27 +2003,15 @@
 static int
 setVersion(TlsConnection *c, int version)
 {
-	if(version > MaxProtoVersion || version < MinProtoVersion)
+	if(version < MinProtoVersion)
 		return -1;
 	if(version > c->version)
 		version = c->version;
-	if(version == SSL3Version) {
+	else
 		c->version = version;
-		c->finished.n = SSL3FinishedLen;
-	}else {
-		c->version = version;
-		c->finished.n = TLSFinishedLen;
-	}
 	return fprint(c->ctl, "version 0x%x", version);
 }
 
-// confirm that received Finished message matches the expected value
-static int
-finishedMatch(TlsConnection *c, Finished *f)
-{
-	return tsmemcmp(f->verify, c->finished.verify, f->n) == 0;
-}
-
 // free memory associated with TlsConnection struct
 //		(but don't close the TLS channel itself)
 static void
@@ -2390,68 +2349,6 @@
 		hmac_sha2_256, SHA2_256dlen);
 }
 
-static void
-sslPRF(uchar *buf, int nbuf, uchar *key, int nkey, char *label, uchar *seed, int nseed)
-{
-	uchar sha1dig[SHA1dlen], md5dig[MD5dlen], tmp[26];
-	DigestState *s;
-	int i, n, len;
-
-	USED(label);
-	len = 1;
-	while(nbuf > 0){
-		if(len > 26)
-			return;
-		for(i = 0; i < len; i++)
-			tmp[i] = 'A' - 1 + len;
-		s = sha1(tmp, len, nil, nil);
-		s = sha1(key, nkey, nil, s);
-		sha1(seed, nseed, sha1dig, s);
-		s = md5(key, nkey, nil, nil);
-		md5(sha1dig, SHA1dlen, md5dig, s);
-		n = MD5dlen;
-		if(n > nbuf)
-			n = nbuf;
-		memmove(buf, md5dig, n);
-		buf += n;
-		nbuf -= n;
-		len++;
-	}
-}
-
-static void
-sslSetFinished(TlsSec *sec, HandshakeHash hsh, uchar *finished, int isclient)
-{
-	DigestState *s;
-	uchar h0[MD5dlen], h1[SHA1dlen], pad[48];
-	char *label;
-
-	if(isclient)
-		label = "CLNT";
-	else
-		label = "SRVR";
-
-	md5((uchar*)label, 4, nil, &hsh.md5);
-	md5(sec->sec, MasterSecretSize, nil, &hsh.md5);
-	memset(pad, 0x36, 48);
-	md5(pad, 48, nil, &hsh.md5);
-	md5(nil, 0, h0, &hsh.md5);
-	memset(pad, 0x5C, 48);
-	s = md5(sec->sec, MasterSecretSize, nil, nil);
-	s = md5(pad, 48, nil, s);
-	md5(h0, MD5dlen, finished, s);
-
-	sha1((uchar*)label, 4, nil, &hsh.sha1);
-	sha1(sec->sec, MasterSecretSize, nil, &hsh.sha1);
-	memset(pad, 0x36, 40);
-	sha1(pad, 40, nil, &hsh.sha1);
-	sha1(nil, 0, h1, &hsh.sha1);
-	memset(pad, 0x5C, 40);
-	s = sha1(sec->sec, MasterSecretSize, nil, nil);
-	s = sha1(pad, 40, nil, s);
-	sha1(h1, SHA1dlen, finished + MD5dlen, s);
-}
-
 // fill "finished" arg with md5(args)^sha1(args)
 static void
 tls10SetFinished(TlsSec *sec, HandshakeHash hsh, uchar *finished, int isclient)
@@ -2460,6 +2357,8 @@
 	char *label;
 
 	// get current hash value, but allow further messages to be hashed in
+	hsh.md5.malloced = 0;
+	hsh.sha1.malloced = 0;
 	md5(nil, 0, h, &hsh.md5);
 	sha1(nil, 0, h+MD5dlen, &hsh.sha1);
 
@@ -2467,7 +2366,7 @@
 		label = "client finished";
 	else
 		label = "server finished";
-	tls10PRF(finished, TLSFinishedLen, sec->sec, MasterSecretSize, label, h, sizeof(h));
+	tls10PRF(finished, FinishedLen, sec->sec, MasterSecretSize, label, h, sizeof(h));
 }
 
 static void
@@ -2477,6 +2376,7 @@
 	char *label;
 
 	// get current hash value, but allow further messages to be hashed in
+	hsh.sha2_256.malloced = 0;
 	sha2_256(nil, 0, seed, &hsh.sha2_256);
 
 	if(isclient)
@@ -2483,7 +2383,7 @@
 		label = "client finished";
 	else
 		label = "server finished";
-	tls12PRF(finished, TLSFinishedLen, sec->sec, MasterSecretSize, label, seed, SHA2_256dlen);
+	tls12PRF(finished, FinishedLen, sec->sec, MasterSecretSize, label, seed, SHA2_256dlen);
 }
 
 static void
@@ -2630,34 +2530,14 @@
 	return epm;
 }
 
-static int
-tlsSecFinished(TlsSec *sec, HandshakeHash hsh, uchar *fin, int nfin, int isclient)
-{
-	if(sec->nfin != nfin){
-		werrstr("invalid finished exchange");
-		return -1;
-	}
-	hsh.md5.malloced = 0;
-	hsh.sha1.malloced = 0;
-	hsh.sha2_256.malloced = 0;
-	(*sec->setFinished)(sec, hsh, fin, isclient);
-	return 0;
-}
-
 static void
 tlsSecVers(TlsSec *sec, int v)
 {
-	if(v == SSL3Version){
-		sec->setFinished = sslSetFinished;
-		sec->nfin = SSL3FinishedLen;
-		sec->prf = sslPRF;
-	}else if(v < TLS12Version) {
+	if(v < TLS12Version){
 		sec->setFinished = tls10SetFinished;
-		sec->nfin = TLSFinishedLen;
 		sec->prf = tls10PRF;
-	}else {
+	}else{
 		sec->setFinished = tls12SetFinished;
-		sec->nfin = TLSFinishedLen;
 		sec->prf = tls12PRF;
 	}
 }

  parent reply	other threads:[~2021-10-23 20:20 UTC|newest]

Thread overview: 23+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-10-22  1:48 ori
2021-10-22  1:58 ` sl
2021-10-22  2:26   ` ori
2021-10-22  2:44     ` Stanley Lieber
2021-10-22 10:19       ` Philip Silva
2021-10-22 15:32         ` ori
2021-10-22 20:26   ` Stuart Morrow
2021-12-01  2:13     ` sl
2021-12-01  2:13     ` sl
2021-10-22 11:43 ` kemal
2021-10-22 14:31   ` kemal
2021-10-22 14:36     ` kemal
2021-10-23 15:47       ` ori
2021-10-23 16:12         ` cinap_lenrek
2021-10-23 16:17           ` ori
2021-10-23 20:13         ` kemal [this message]
2021-10-24 11:46           ` kemal
2021-10-24 16:06             ` cinap_lenrek
2021-10-24 16:14             ` cinap_lenrek
2021-10-23 11:18     ` kemal
2021-12-13  2:30 ` ori
2021-12-14 19:45   ` theinicke
2021-12-15  1:49     ` ori

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to='CABO6shdSD2WOr0VoG_dNP02uBrCjwqUaH32=NYKQG5AngtLp9w@mail.gmail.com' \
    --to=kemalinanc8@gmail.com \
    --cc=9front@9front.org \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for NNTP newsgroup(s).