From: kemal <kemalinanc8@gmail.com>
To: 9front@9front.org
Subject: Re: [9front] intent to delete: devssl, cpu, oexportfs, import
Date: Sun, 24 Oct 2021 14:46:14 +0300 [thread overview]
Message-ID: <CABO6shfizVvY3qmr+wwRrhrD493YMu3kcJ-zmXVwjovz+rbaAQ@mail.gmail.com> (raw)
In-Reply-To: <CABO6shdSD2WOr0VoG_dNP02uBrCjwqUaH32=NYKQG5AngtLp9w@mail.gmail.com>
[-- Attachment #1: Type: text/plain, Size: 808 bytes --]
i am sending a new diff, again. i apologise for sending 4 different
diffs for this, i definitely should have checked my diff better...
> 1. don't reject protocol versions that is higher than 0x03ff.
> this behavior is useless.
it is if it's checking the clienthello/serverhello version,
but not if we're checking the record layer version! it might
accept non-TLS data if it doesn't check `major version == 0x03`.
add that behavior back for devtls.
also, 2 more problems i saw in version negotiation code:
1. when setVersion fails, code sends a "illegal_parameter" alert
but "protocol_version" is more suitable and the standard way
for this. send "protocol_version" instead.
2. tlsClient2 should abort if the server sends a version higher
than `c->version`. fix up.
the new (and last) diff is attached.
[-- Attachment #2: diff.txt --]
[-- Type: text/plain, Size: 31496 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;
@@ -757,13 +741,13 @@
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 */
+ rcvError(tr, EUnexpectedMessage, "invalid initial SSL2-like message");
+ }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>>8 != 0x03))
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,
@@ -365,9 +355,8 @@
static int msgSend(TlsConnection *c, Msg *m, int act);
static void tlsError(TlsConnection *c, int err, char *msg, ...);
#pragma varargck argpos tlsError 3
-static int setVersion(TlsConnection *c, int version);
+static int setVersion(TlsConnection *c, int version, int client);
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,
@@ -713,8 +699,8 @@
}
if(trace)
trace("ClientHello version %x\n", m.u.clientHello.version);
- if(setVersion(c, m.u.clientHello.version) < 0) {
- tlsError(c, EIllegalParameter, "incompatible version");
+ if(setVersion(c, m.u.clientHello.version, 0) < 0){
+ tlsError(c, EProtocolVersion, "incompatible version");
goto Err;
}
if(c->version < ProtocolVersion
@@ -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)
@@ -1056,8 +1036,8 @@
tlsError(c, EUnexpectedMessage, "expected a server hello");
goto Err;
}
- if(setVersion(c, m.u.serverHello.version) < 0) {
- tlsError(c, EIllegalParameter, "incompatible version: %r");
+ if(setVersion(c, m.u.serverHello.version, 1) < 0){
+ tlsError(c, EProtocolVersion, "incompatible version: %r");
goto Err;
}
tlsSecVers(c->sec, c->version);
@@ -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 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. */
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;
}
@@ -2030,29 +2001,20 @@
// commit to specific version number
static int
-setVersion(TlsConnection *c, int version)
+setVersion(TlsConnection *c, int version, int client)
{
- if(version > MaxProtoVersion || version < MinProtoVersion)
+ if(version < MinProtoVersion)
return -1;
- if(version > c->version)
- version = c->version;
- if(version == SSL3Version) {
+ if(version > c->version){
+ if(client)
+ return -1;
+ else
+ version = c->version;
+ }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 +2352,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 +2360,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 +2369,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 +2379,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 +2386,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 +2533,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;
}
}
next prev parent reply other threads:[~2021-10-24 12:01 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
2021-10-24 11:46 ` kemal [this message]
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=CABO6shfizVvY3qmr+wwRrhrD493YMu3kcJ-zmXVwjovz+rbaAQ@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).