changelog shortlog tags branches files raw gz bz2 help

Mercurial > hg > plan9front / changeset: libsec: ecdsa client support for tlshand, cleanups

changeset 5069: 467142072a11
parent 5068: fa3700dc38f9
child 5070: 3f9227bd4f1d
author: cinap_lenrek@felloff.net
date: Mon, 01 Feb 2016 21:34:49 +0100
files: sys/include/libsec.h sys/man/2/ec sys/man/2/rsa sys/src/cmd/auth/factotum/ecdsa.c sys/src/cmd/auth/rsa2csr.c sys/src/cmd/auth/rsa2x509.c sys/src/libsec/port/ecc.c sys/src/libsec/port/mkfile sys/src/libsec/port/secp256k1.mp sys/src/libsec/port/secp256r1.mp sys/src/libsec/port/tlshand.c sys/src/libsec/port/x509.c
description: libsec: ecdsa client support for tlshand, cleanups
     1.1--- a/sys/include/libsec.h
     1.2+++ b/sys/include/libsec.h
     1.3@@ -339,11 +339,11 @@ RSApriv*	asn1toRSApriv(uchar*, int);
     1.4 void		asn1dump(uchar *der, int len);
     1.5 uchar*		decodePEM(char *s, char *type, int *len, char **new_s);
     1.6 PEMChain*	decodepemchain(char *s, char *type);
     1.7-uchar*		X509gen(RSApriv *priv, char *subj, ulong valid[2], int *certlen);
     1.8-uchar*		X509req(RSApriv *priv, char *subj, int *certlen);
     1.9-char*		X509verifydigest(uchar *sig, int siglen, uchar *edigest, int edigestlen, RSApub *pk);
    1.10-char*		X509verifydata(uchar *sig, int siglen, uchar *data, int datalen, RSApub *pk);
    1.11-char*		X509verify(uchar *cert, int ncert, RSApub *pk);
    1.12+uchar*		X509rsagen(RSApriv *priv, char *subj, ulong valid[2], int *certlen);
    1.13+uchar*		X509rsareq(RSApriv *priv, char *subj, int *certlen);
    1.14+char*		X509rsaverifydigest(uchar *sig, int siglen, uchar *edigest, int edigestlen, RSApub *pk);
    1.15+char*		X509rsaverify(uchar *cert, int ncert, RSApub *pk);
    1.16+
    1.17 void		X509dump(uchar *cert, int ncert);
    1.18 
    1.19 /*
    1.20@@ -487,11 +487,14 @@ typedef struct ECdomain{
    1.21 	mpint *p;
    1.22 	mpint *a;
    1.23 	mpint *b;
    1.24-	ECpoint *G;
    1.25+	ECpoint G;
    1.26 	mpint *n;
    1.27 	mpint *h;
    1.28 } ECdomain;
    1.29 
    1.30+void	ecdominit(ECdomain *, void (*init)(mpint *p, mpint *a, mpint *b, mpint *x, mpint *y, mpint *n, mpint *h));
    1.31+void	ecdomfree(ECdomain *);
    1.32+
    1.33 void	ecassign(ECdomain *, ECpoint *old, ECpoint *new);
    1.34 void	ecadd(ECdomain *, ECpoint *a, ECpoint *b, ECpoint *s);
    1.35 void	ecmul(ECdomain *, ECpoint *a, mpint *k, ECpoint *s);
    1.36@@ -504,6 +507,18 @@ int	ecdsaverify(ECdomain *, ECpub *, uch
    1.37 void	base58enc(uchar *, char *, int);
    1.38 int	base58dec(char *, uchar *, int);
    1.39 
    1.40+ECpub*	ecdecodepub(ECdomain *dom, uchar *, int);
    1.41+int	ecencodepub(ECdomain *dom, ECpub *, uchar *, int);
    1.42+void	ecpubfree(ECpub *);
    1.43+
    1.44+ECpub*	X509toECpub(uchar *cert, int ncert, ECdomain *dom);
    1.45+char*	X509ecdsaverifydigest(uchar *sig, int siglen, uchar *edigest, int edigestlen, ECdomain *dom, ECpub *pub);
    1.46+char*	X509ecdsaverify(uchar *sig, int siglen, ECdomain *dom, ECpub *pub);
    1.47+
    1.48+/* curves */
    1.49+void	secp256r1(mpint *p, mpint *a, mpint *b, mpint *x, mpint *y, mpint *n, mpint *h);
    1.50+void	secp256k1(mpint *p, mpint *a, mpint *b, mpint *x, mpint *y, mpint *n, mpint *h);
    1.51+
    1.52 DigestState*	ripemd160(uchar *, ulong, uchar *, DigestState *);
    1.53 
    1.54 /*
     2.1--- a/sys/man/2/ec
     2.2+++ b/sys/man/2/ec
     2.3@@ -19,6 +19,12 @@ ecdsaverify \- elliptic curve cryptograp
     2.4 .B #include <libsec.h>
     2.5 .PP
     2.6 .B
     2.7+void	ecdominit(ECdomain *dom, void (*init)(mpint *p, mpint *a, mpint *b, mpint *x, mpint *y, mpint *n, mpint *h));
     2.8+.PP
     2.9+.B
    2.10+void	ecdomfree(ECdomain *dom);
    2.11+.PP
    2.12+.B
    2.13 void	ecassign(ECdomain *dom, ECpoint *old, ECpoint *new);
    2.14 .PP
    2.15 .B
    2.16@@ -54,6 +60,19 @@ Points on the curve are represented by
    2.17 .B ECpoint
    2.18 structs.
    2.19 .PP
    2.20+.B ecdominit
    2.21+initializes a
    2.22+.B ECdomain
    2.23+struct and calls the
    2.24+.B init
    2.25+function such as
    2.26+.B secp256r1
    2.27+which fills in the parameters of the curve.
    2.28+.PP
    2.29+.B ecdomfree
    2.30+frees the parameters of the curve and zeros the struct. It does
    2.31+not free the memory of the struct itself.
    2.32+.PP
    2.33 .BR ecassign ", " ecadd " and " ecmul
    2.34 are analogous to their counterparts in
    2.35 .IR mp (2).
     3.1--- a/sys/man/2/rsa
     3.2+++ b/sys/man/2/rsa
     3.3@@ -12,8 +12,9 @@ rsaprivtopub,
     3.4 rsapuballoc,
     3.5 rsapubfree,
     3.6 X509toRSApub,
     3.7-X509gen,
     3.8-X509verify \- RSA encryption algorithm
     3.9+X509rsagen,
    3.10+X509rsareq,
    3.11+X509rsaverify \- RSA encryption algorithm
    3.12 .SH SYNOPSIS
    3.13 .B #include <u.h>
    3.14 .br
    3.15@@ -61,13 +62,13 @@ void		asn1dump(uchar *der, int len)
    3.16 uchar*	decodePEM(char *s, char *type, int *len, char **new_s)
    3.17 .PP
    3.18 .B
    3.19-uchar*	X509gen(RSApriv *priv, char *subj, ulong valid[2], int *certlen);
    3.20+uchar*	X509rsagen(RSApriv *priv, char *subj, ulong valid[2], int *certlen);
    3.21 .PP
    3.22 .B
    3.23-uchar*	X509req(RSApriv *priv, char *subj, int *certlen);
    3.24+uchar*	X509rsareq(RSApriv *priv, char *subj, int *certlen);
    3.25 .PP
    3.26 .B
    3.27-char*	X509verify(uchar *cert, int ncert, RSApub *pk)
    3.28+char*	X509rsaverify(uchar *cert, int ncert, RSApub *pk)
    3.29 .DT
    3.30 .SH DESCRIPTION
    3.31 RSA is a public key encryption algorithm.  The owner of a key publishes
    3.32@@ -147,12 +148,12 @@ to convert to binary before computing th
    3.33 For the special case of
    3.34 certificates signed by a known trusted key
    3.35 (in a single step, without certificate chains),
    3.36-.I X509verify
    3.37+.I X509rsaverify
    3.38 checks the signature on
    3.39 .IR cert .
    3.40 It returns nil if successful, else an error string.
    3.41 .PP
    3.42-.I X509gen
    3.43+.I X509rsagen
    3.44 creates a self-signed X.509 certificate, given an RSA keypair
    3.45 .IR priv ,
    3.46 a issuer/subject string
     4.1--- a/sys/src/cmd/auth/factotum/ecdsa.c
     4.2+++ b/sys/src/cmd/auth/factotum/ecdsa.c
     4.3@@ -42,7 +42,7 @@ decryptkey(Fsstate *fss, char *key, char
     4.4 	st->p.d = betomp(keyenc + 1, 32, nil);
     4.5 	st->p.x = mpnew(0);
     4.6 	st->p.y = mpnew(0);
     4.7-	ecmul(&dom, dom.G, st->p.d, &st->p);
     4.8+	ecmul(&dom, &dom.G, st->p.d, &st->p);
     4.9 	return RpcOk;
    4.10 }
    4.11 
    4.12@@ -56,14 +56,8 @@ ecdsainit(Proto *, Fsstate *fss)
    4.13 	char *key, *password;
    4.14 	Attr *attr;
    4.15 
    4.16-	if(dom.p == nil){
    4.17-		dom.p = strtomp("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEFFFFFC2F", nil, 16, nil);
    4.18-		dom.a = uitomp(0, nil);
    4.19-		dom.b = uitomp(7, nil);
    4.20-		dom.n = strtomp("FFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141", nil, 16, nil);
    4.21-		dom.h = uitomp(1, nil);
    4.22-		dom.G = strtoec(&dom, "0279BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798", nil, nil);
    4.23-	}
    4.24+	if(dom.p == nil)
    4.25+		ecdominit(&dom, secp256k1);
    4.26 	fss->ps = nil;
    4.27 	if((iscli = isclient(_strfindattr(fss->attr, "role"))) < 0)
    4.28 		return failure(fss, nil);
     5.1--- a/sys/src/cmd/auth/rsa2csr.c
     5.2+++ b/sys/src/cmd/auth/rsa2csr.c
     5.3@@ -34,7 +34,7 @@ main(int argc, char **argv)
     5.4 	if((key = getkey(argc-1, argv+1, 1, nil)) == nil)
     5.5 		sysfatal("%r");
     5.6 
     5.7-	cert = X509req(key, argv[0], &len);
     5.8+	cert = X509rsareq(key, argv[0], &len);
     5.9 	if(cert == nil)
    5.10 		sysfatal("X509req: %r");
    5.11 
     6.1--- a/sys/src/cmd/auth/rsa2x509.c
     6.2+++ b/sys/src/cmd/auth/rsa2x509.c
     6.3@@ -41,7 +41,7 @@ main(int argc, char **argv)
     6.4 	if((key = getkey(argc-1, argv+1, 1, nil)) == nil)
     6.5 		sysfatal("%r");
     6.6 
     6.7-	cert = X509gen(key, argv[0], valid, &len);
     6.8+	cert = X509rsagen(key, argv[0], valid, &len);
     6.9 	if(cert == nil)
    6.10 		sysfatal("X509gen: %r");
    6.11 
     7.1--- a/sys/src/libsec/port/ecc.c
     7.2+++ b/sys/src/libsec/port/ecc.c
     7.3@@ -407,7 +407,7 @@ ecgen(ECdomain *dom, ECpriv *p)
     7.4 		if(mpcmp(p->d, mpzero) > 0 && mpcmp(p->d, dom->n) < 0)
     7.5 			break;
     7.6 	}
     7.7-	ecmul(dom, dom->G, p->d, p);
     7.8+	ecmul(dom, &dom->G, p->d, p);
     7.9 	return p;
    7.10 }
    7.11 
    7.12@@ -468,7 +468,7 @@ ecdsaverify(ECdomain *dom, ECpub *pub, u
    7.13 	mpmod(u1, dom->n, u1);
    7.14 	mpmul(r, t, u2);
    7.15 	mpmod(u2, dom->n, u2);
    7.16-	ecmul(dom, dom->G, u1, &R);
    7.17+	ecmul(dom, &dom->G, u1, &R);
    7.18 	ecmul(dom, pub, u2, &S);
    7.19 	ecadd(dom, &R, &S, &R);
    7.20 	ret = 0;
    7.21@@ -540,3 +540,79 @@ base58dec(char *src, uchar *dst, int len
    7.22 	mpfree(b);
    7.23 	return 0;
    7.24 }
    7.25+
    7.26+void
    7.27+ecdominit(ECdomain *dom, void (*init)(mpint *p, mpint *a, mpint *b, mpint *x, mpint *y, mpint *n, mpint *h))
    7.28+{
    7.29+	memset(dom, 0, sizeof(*dom));
    7.30+	dom->p = mpnew(0);
    7.31+	dom->a = mpnew(0);
    7.32+	dom->b = mpnew(0);
    7.33+	dom->G.x = mpnew(0);
    7.34+	dom->G.y = mpnew(0);
    7.35+	dom->n = mpnew(0);
    7.36+	dom->h = mpnew(0);
    7.37+	if(init){
    7.38+		(*init)(dom->p, dom->a, dom->b, dom->G.x, dom->G.y, dom->n, dom->h);
    7.39+		dom->p = mpfield(dom->p);
    7.40+	}
    7.41+}
    7.42+
    7.43+void
    7.44+ecdomfree(ECdomain *dom)
    7.45+{
    7.46+	mpfree(dom->p);
    7.47+	mpfree(dom->a);
    7.48+	mpfree(dom->b);
    7.49+	mpfree(dom->G.x);
    7.50+	mpfree(dom->G.y);
    7.51+	mpfree(dom->n);
    7.52+	mpfree(dom->h);
    7.53+	memset(dom, 0, sizeof(*dom));
    7.54+}
    7.55+
    7.56+int
    7.57+ecencodepub(ECdomain *dom, ECpub *pub, uchar *data, int len)
    7.58+{
    7.59+	int n;
    7.60+
    7.61+	n = (mpsignif(dom->p)+7)/8;
    7.62+	if(len < 1 + 2*n)
    7.63+		return 0;
    7.64+	len = 1 + 2*n;
    7.65+	data[0] = 0x04;
    7.66+	mptober(pub->x, data+1, n);
    7.67+	mptober(pub->y, data+1+n, n);
    7.68+	return len;
    7.69+}
    7.70+
    7.71+ECpub*
    7.72+ecdecodepub(ECdomain *dom, uchar *data, int len)
    7.73+{
    7.74+	ECpub *pub;
    7.75+	int n;
    7.76+
    7.77+	n = (mpsignif(dom->p)+7)/8;
    7.78+	if(len != 1 + 2*n || data[0] != 0x04)
    7.79+		return nil;
    7.80+	pub = mallocz(sizeof(*pub), 1);
    7.81+	if(pub == nil)
    7.82+		return nil;
    7.83+	pub->x = betomp(data+1, n, nil);
    7.84+	pub->y = betomp(data+1+n, n, nil);
    7.85+	if(!ecpubverify(dom, pub)){
    7.86+		ecpubfree(pub);
    7.87+		pub = nil;
    7.88+	}
    7.89+	return pub;
    7.90+}
    7.91+
    7.92+void
    7.93+ecpubfree(ECpub *p)
    7.94+{
    7.95+	if(p == nil)
    7.96+		return;
    7.97+	mpfree(p->x);
    7.98+	mpfree(p->y);
    7.99+	free(p);
   7.100+}
     8.1--- a/sys/src/libsec/port/mkfile
     8.2+++ b/sys/src/libsec/port/mkfile
     8.3@@ -30,6 +30,10 @@ CFILES = des.c desmodes.c desECB.c desCB
     8.4 	hkdf.c\
     8.5 	ccpoly.c\
     8.6 	tsmemcmp.c\
     8.7+	secp256r1.c\
     8.8+	secp256k1.c\
     8.9+
    8.10+CLEANFILES=secp256r1.c secp256k1.c
    8.11 
    8.12 ALLOFILES=${CFILES:%.c=%.$O}
    8.13 
    8.14@@ -46,6 +50,12 @@ UPDATE=mkfile\
    8.15 
    8.16 </sys/src/cmd/mksyslib
    8.17 
    8.18+%.c:D:	%.mp
    8.19+	echo '#include <u.h>' > $target
    8.20+	echo '#include <libc.h>' >> $target
    8.21+	echo '#include <mp.h>' >> $target
    8.22+	mpc $prereq >> $target
    8.23+	
    8.24 $O.rsatest: rsatest.$O
    8.25 	$LD -o $target $prereq
    8.26 
     9.1new file mode 100644
     9.2--- /dev/null
     9.3+++ b/sys/src/libsec/port/secp256k1.mp
     9.4@@ -0,0 +1,10 @@
     9.5+# E: y² = x³ + ax + b 
     9.6+secp256k1(p,a,b,x,y,n,h) {
     9.7+	p = 2^256 - 2^32 - 2^9 - 2^8 - 2^7 - 2^6 - 2^4 - 1;
     9.8+	a = 0;
     9.9+	b = 7;
    9.10+	x = 0x79BE667EF9DCBBAC55A06295CE870B07029BFCDB2DCE28D959F2815B16F81798;
    9.11+	y = 0x483ADA7726A3C4655DA4FBFC0E1108A8FD17B448A68554199C47D08FFB10D4B8;
    9.12+	n = 0xFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFFEBAAEDCE6AF48A03BBFD25E8CD0364141;
    9.13+	h = 1;
    9.14+}
    10.1new file mode 100644
    10.2--- /dev/null
    10.3+++ b/sys/src/libsec/port/secp256r1.mp
    10.4@@ -0,0 +1,10 @@
    10.5+# E: y² = x³ + ax + b 
    10.6+secp256r1(p,a,b,x,y,n,h) {
    10.7+	p = 2^256 - 2^224 + 2^192 + 2^96 - 1;
    10.8+	a = p - 3;
    10.9+	b = 0x5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B;
   10.10+	x = 0x6B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C296;
   10.11+	y = 0x4FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5;
   10.12+	n = 0xFFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551;
   10.13+	h = 1;
   10.14+}
    11.1--- a/sys/src/libsec/port/tlshand.c
    11.2+++ b/sys/src/libsec/port/tlshand.c
    11.3@@ -19,6 +19,7 @@ enum {
    11.4 	SSL3FinishedLen = MD5dlen+SHA1dlen,
    11.5 	MaxKeyData = 160,	// amount of secret we may need
    11.6 	MaxChunk = 1<<15,
    11.7+	MAXdlen = SHA2_512dlen,
    11.8 	RandomSize = 32,
    11.9 	SidSize = 32,
   11.10 	MasterSecretSize = 48,
   11.11@@ -48,14 +49,7 @@ typedef struct Algs{
   11.12 
   11.13 typedef struct Namedcurve{
   11.14 	int tlsid;
   11.15-	char *name;
   11.16-
   11.17-	char *p;
   11.18-	char *a;
   11.19-	char *b;
   11.20-	char *G;
   11.21-	char *n;
   11.22-	char *h;
   11.23+	void (*init)(mpint *p, mpint *a, mpint *b, mpint *x, mpint *y, mpint *n, mpint *h);
   11.24 } Namedcurve;
   11.25 
   11.26 typedef struct Finished{
   11.27@@ -279,12 +273,15 @@ enum {
   11.28 	TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA	= 0XC013,
   11.29 	TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA	= 0XC014,
   11.30 	TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256	= 0xC027,
   11.31+	TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256	= 0xC023,
   11.32 
   11.33 	TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305	= 0xCCA8,
   11.34+	TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305	= 0xCCA9,
   11.35 	TLS_DHE_RSA_WITH_CHACHA20_POLY1305	= 0xCCAA,
   11.36 
   11.37-	GOOGLE_ECDHE_RSA_WITH_CHACHA20_POLY1305	= 0xCC13,
   11.38-	GOOGLE_DHE_RSA_WITH_CHACHA20_POLY1305	= 0xCC15,
   11.39+	GOOGLE_ECDHE_RSA_WITH_CHACHA20_POLY1305		= 0xCC13,
   11.40+	GOOGLE_ECDHE_ECDSA_WITH_CHACHA20_POLY1305	= 0xCC14,
   11.41+	GOOGLE_DHE_RSA_WITH_CHACHA20_POLY1305		= 0xCC15,
   11.42 
   11.43 	TLS_PSK_WITH_CHACHA20_POLY1305		= 0xCCAB,
   11.44 	TLS_PSK_WITH_AES_128_CBC_SHA256		= 0x00AE,
   11.45@@ -299,11 +296,14 @@ enum {
   11.46 
   11.47 static Algs cipherAlgs[] = {
   11.48 	{"ccpoly96_aead", "clear", 2*(32+12), TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305},
   11.49+	{"ccpoly96_aead", "clear", 2*(32+12), TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305},
   11.50 	{"ccpoly96_aead", "clear", 2*(32+12), TLS_DHE_RSA_WITH_CHACHA20_POLY1305},
   11.51 
   11.52 	{"ccpoly64_aead", "clear", 2*32, GOOGLE_ECDHE_RSA_WITH_CHACHA20_POLY1305},
   11.53+	{"ccpoly64_aead", "clear", 2*32, GOOGLE_ECDHE_ECDSA_WITH_CHACHA20_POLY1305},
   11.54 	{"ccpoly64_aead", "clear", 2*32, GOOGLE_DHE_RSA_WITH_CHACHA20_POLY1305},
   11.55 
   11.56+	{"aes_128_cbc", "sha256", 2*(16+16+SHA2_256dlen), TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256},
   11.57 	{"aes_128_cbc", "sha256", 2*(16+16+SHA2_256dlen), TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256},
   11.58 	{"aes_128_cbc", "sha1", 2*(16+16+SHA1dlen), TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA},
   11.59 	{"aes_256_cbc", "sha1", 2*(32+16+SHA1dlen), TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA},
   11.60@@ -328,21 +328,32 @@ static uchar compressors[] = {
   11.61 };
   11.62 
   11.63 static Namedcurve namedcurves[] = {
   11.64-{0x0017, "secp256r1",
   11.65-	"FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFF",
   11.66-	"FFFFFFFF00000001000000000000000000000000FFFFFFFFFFFFFFFFFFFFFFFC",
   11.67-	"5AC635D8AA3A93E7B3EBBD55769886BC651D06B0CC53B0F63BCE3C3E27D2604B",
   11.68-	"046B17D1F2E12C4247F8BCE6E563A440F277037D812DEB33A0F4A13945D898C2964FE342E2FE1A7F9B8EE7EB4A7C0F9E162BCE33576B315ECECBB6406837BF51F5",
   11.69-	"FFFFFFFF00000000FFFFFFFFFFFFFFFFBCE6FAADA7179E84F3B9CAC2FC632551",
   11.70-	"1"}
   11.71+	0x0017, secp256r1,
   11.72 };
   11.73 
   11.74 static uchar pointformats[] = {
   11.75 	CompressionNull /* support of uncompressed point format is mandatory */
   11.76 };
   11.77 
   11.78-// signature algorithms (only RSA at the moment)
   11.79+static struct {
   11.80+	DigestState* (*fun)(uchar*, ulong, uchar*, DigestState*);
   11.81+	int len;
   11.82+} hashfun[] = {
   11.83+	[0x01]	{md5,		MD5dlen},
   11.84+	[0x02]	{sha1,		SHA1dlen},
   11.85+	[0x03]	{sha2_224,	SHA2_224dlen},
   11.86+	[0x04]	{sha2_256,	SHA2_256dlen},
   11.87+	[0x05]	{sha2_384,	SHA2_384dlen},
   11.88+	[0x06]	{sha2_512,	SHA2_512dlen},
   11.89+};
   11.90+
   11.91+// signature algorithms (only RSA and ECDSA at the moment)
   11.92 static int sigalgs[] = {
   11.93+	0x0603,		/* SHA512 ECDSA */
   11.94+	0x0503,		/* SHA384 ECDSA */
   11.95+	0x0403,		/* SHA256 ECDSA */
   11.96+	0x0203,		/* SHA1 ECDSA */
   11.97+
   11.98 	0x0601,		/* SHA512 RSA */
   11.99 	0x0501,		/* SHA384 RSA */
  11.100 	0x0401,		/* SHA256 RSA */
  11.101@@ -421,7 +432,6 @@ static void freeints(Ints* b);
  11.102 
  11.103 /* x509.c */
  11.104 extern mpint*	pkcs1padbuf(uchar *buf, int len, mpint *modulus);
  11.105-extern int	pkcs1decryptsignature(uchar *sig, int siglen, RSApub *pk, uchar **pbuf);
  11.106 extern int	X509encodesignature_sha256(uchar digest[SHA2_256dlen], uchar *buf, int len);
  11.107 
  11.108 //================= client/server ========================
  11.109@@ -869,11 +879,16 @@ static int
  11.110 isECDHE(int tlsid)
  11.111 {
  11.112 	switch(tlsid){
  11.113+	case TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305:
  11.114+	case TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305:
  11.115+
  11.116+	case GOOGLE_ECDHE_ECDSA_WITH_CHACHA20_POLY1305:
  11.117+	case GOOGLE_ECDHE_RSA_WITH_CHACHA20_POLY1305:
  11.118+
  11.119+	case TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256:
  11.120 	case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA256:
  11.121 	case TLS_ECDHE_RSA_WITH_AES_128_CBC_SHA:
  11.122 	case TLS_ECDHE_RSA_WITH_AES_256_CBC_SHA:
  11.123-	case TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305:
  11.124-	case GOOGLE_ECDHE_RSA_WITH_CHACHA20_POLY1305:
  11.125 		return 1;
  11.126 	}
  11.127 	return 0;
  11.128@@ -932,47 +947,14 @@ Out:
  11.129 	return epm;
  11.130 }
  11.131 
  11.132-static ECpoint*
  11.133-bytestoec(ECdomain *dom, Bytes *bp, ECpoint *ret)
  11.134-{
  11.135-	char *hex = "0123456789ABCDEF";
  11.136-	char *s;
  11.137-	int i;
  11.138-
  11.139-	s = emalloc(2*bp->len + 1);
  11.140-	for(i=0; i < bp->len; i++){
  11.141-		s[2*i] = hex[bp->data[i]>>4 & 15];
  11.142-		s[2*i+1] = hex[bp->data[i] & 15];
  11.143-	}
  11.144-	s[2*bp->len] = '\0';
  11.145-	ret = strtoec(dom, s, nil, ret);
  11.146-	free(s);
  11.147-	return ret;
  11.148-}
  11.149-
  11.150-static Bytes*
  11.151-ectobytes(int type, ECpoint *p)
  11.152-{
  11.153-	Bytes *bx, *by, *bp;
  11.154-
  11.155-	bx = mptobytes(p->x);
  11.156-	by = mptobytes(p->y);
  11.157-	bp = newbytes(bx->len + by->len + 1);
  11.158-	bp->data[0] =  type;
  11.159-	memmove(bp->data+1, bx->data, bx->len);
  11.160-	memmove(bp->data+1+bx->len, by->data, by->len);
  11.161-	freebytes(bx);
  11.162-	freebytes(by);
  11.163-	return bp;
  11.164-}
  11.165-
  11.166 static Bytes*
  11.167 tlsSecECDHEc(TlsSec *sec, uchar *srandom, int vers, int curve, Bytes *Ys)
  11.168 {
  11.169 	Namedcurve *nc, *enc;
  11.170 	Bytes *epm;
  11.171 	ECdomain dom;
  11.172-	ECpoint G, K, Y;
  11.173+	ECpub *pub;
  11.174+	ECpoint K;
  11.175 	ECpriv Q;
  11.176 
  11.177 	if(Ys == nil)
  11.178@@ -990,18 +972,12 @@ tlsSecECDHEc(TlsSec *sec, uchar *srandom
  11.179 	if(setVers(sec, vers) < 0)
  11.180 		return nil;
  11.181 	
  11.182-	epm = nil;
  11.183-
  11.184-	memset(&dom, 0, sizeof(dom));
  11.185-	dom.p = mpfield(strtomp(nc->p, nil, 16, nil));
  11.186-	dom.a = strtomp(nc->a, nil, 16, nil);
  11.187-	dom.b = strtomp(nc->b, nil, 16, nil);
  11.188-	dom.n = strtomp(nc->n, nil, 16, nil);
  11.189-	dom.h = strtomp(nc->h, nil, 16, nil);
  11.190-
  11.191-	memset(&G, 0, sizeof(G));
  11.192-	G.x = mpnew(0);
  11.193-	G.y = mpnew(0);
  11.194+	ecdominit(&dom, nc->init);
  11.195+	pub = ecdecodepub(&dom, Ys->data, Ys->len);
  11.196+	if(pub == nil){
  11.197+		ecdomfree(&dom);
  11.198+		return nil;
  11.199+	}
  11.200 
  11.201 	memset(&Q, 0, sizeof(Q));
  11.202 	Q.x = mpnew(0);
  11.203@@ -1012,48 +988,22 @@ tlsSecECDHEc(TlsSec *sec, uchar *srandom
  11.204 	K.x = mpnew(0);
  11.205 	K.y = mpnew(0);
  11.206 
  11.207-	memset(&Y, 0, sizeof(Y));
  11.208-	Y.x = mpnew(0);
  11.209-	Y.y = mpnew(0);
  11.210-
  11.211-	if(dom.p == nil || dom.a == nil || dom.b == nil || dom.n == nil || dom.h == nil)
  11.212-		goto Out;
  11.213-
  11.214-	dom.G = strtoec(&dom, nc->G, nil, &G);
  11.215-	if(dom.G == nil)
  11.216-		goto Out;
  11.217-
  11.218-	if(bytestoec(&dom, Ys, &Y) == nil)
  11.219-		goto Out;
  11.220-
  11.221-	if(ecgen(&dom, &Q) == nil)
  11.222-		goto Out;
  11.223-
  11.224-	ecmul(&dom, &Y, Q.d, &K);
  11.225-	setMasterSecret(sec, mptobytes(K.x));
  11.226-
  11.227-	/* 0x04 = uncompressed public key */
  11.228-	epm = ectobytes(0x04, &Q);
  11.229-	
  11.230-Out:
  11.231-	mpfree(Y.x);
  11.232-	mpfree(Y.y);
  11.233+	epm = nil;
  11.234+	if(ecgen(&dom, &Q) != nil){
  11.235+		ecmul(&dom, pub, Q.d, &K);
  11.236+		setMasterSecret(sec, mptobytes(K.x));
  11.237+		epm = newbytes(1 + 2*((mpsignif(dom.p)+7)/8));
  11.238+		epm->len = ecencodepub(&dom, &Q, epm->data, epm->len);
  11.239+	}
  11.240 
  11.241 	mpfree(K.x);
  11.242 	mpfree(K.y);
  11.243-
  11.244 	mpfree(Q.x);
  11.245 	mpfree(Q.y);
  11.246 	mpfree(Q.d);
  11.247 
  11.248-	mpfree(G.x);
  11.249-	mpfree(G.y);
  11.250-
  11.251-	mpfree(dom.p);
  11.252-	mpfree(dom.a);
  11.253-	mpfree(dom.b);
  11.254-	mpfree(dom.n);
  11.255-	mpfree(dom.h);
  11.256+	ecpubfree(pub);
  11.257+	ecdomfree(&dom);
  11.258 
  11.259 	return epm;
  11.260 }
  11.261@@ -1061,9 +1011,12 @@ Out:
  11.262 static char*
  11.263 verifyDHparams(TlsConnection *c, Bytes *par, Bytes *sig, int sigalg)
  11.264 {
  11.265-	uchar hashes[MD5dlen+SHA1dlen], *buf;
  11.266+	uchar digest[MAXdlen];
  11.267+	int digestlen;
  11.268+	ECdomain dom;
  11.269+	ECpub *ecpk;
  11.270+	RSApub *rsapk;
  11.271 	Bytes *blob;
  11.272-	RSApub *pk;
  11.273 	char *err;
  11.274 
  11.275 	if(par == nil || par->len <= 0)
  11.276@@ -1072,40 +1025,52 @@ verifyDHparams(TlsConnection *c, Bytes *
  11.277 	if(sig == nil || sig->len <= 0){
  11.278 		if(c->sec->psklen > 0)
  11.279 			return nil;
  11.280-
  11.281 		return "no signature";
  11.282 	}
  11.283 
  11.284 	if(c->cert == nil)
  11.285 		return "no certificate";
  11.286 
  11.287-	pk = X509toRSApub(c->cert->data, c->cert->len, nil, 0);
  11.288-	if(pk == nil)
  11.289-		return "bad certificate";
  11.290-
  11.291 	blob = newbytes(2*RandomSize + par->len);
  11.292 	memmove(blob->data+0*RandomSize, c->crandom, RandomSize);
  11.293 	memmove(blob->data+1*RandomSize, c->srandom, RandomSize);
  11.294 	memmove(blob->data+2*RandomSize, par->data, par->len);
  11.295-	if(c->version >= TLS12Version) {
  11.296-		if((sigalg & 0xFF) == 1)
  11.297-			err = X509verifydata(sig->data, sig->len, blob->data, blob->len, pk);
  11.298-		else
  11.299-			err = "signaure algorithm not RSA";
  11.300+	if(c->version < TLS12Version){
  11.301+		digestlen = MD5dlen + SHA1dlen;
  11.302+		md5(blob->data, blob->len, digest, nil);
  11.303+		sha1(blob->data, blob->len, digest+MD5dlen, nil);
  11.304 	} else {
  11.305-		err = nil;
  11.306-		if(pkcs1decryptsignature(sig->data, sig->len, pk, &buf) != sizeof(hashes))
  11.307-			err = "bad signature";
  11.308-		else {
  11.309-			md5(blob->data, blob->len, hashes, nil);
  11.310-			sha1(blob->data, blob->len, hashes+MD5dlen, nil);
  11.311-			if(tsmemcmp(buf, hashes, sizeof(hashes)) != 0)
  11.312-				err = "digests did not match";
  11.313+		int hashalg = (sigalg>>8) & 0xFF;
  11.314+		digestlen = -1;
  11.315+		if(hashalg < nelem(hashfun) && hashfun[hashalg].fun != nil){
  11.316+			digestlen = hashfun[hashalg].len;
  11.317+			(*hashfun[hashalg].fun)(blob->data, blob->len, digest, nil);
  11.318 		}
  11.319-		free(buf);
  11.320 	}
  11.321 	freebytes(blob);
  11.322-	rsapubfree(pk);
  11.323+
  11.324+	if(digestlen <= 0)
  11.325+		return "unknown signature digest algorithm";
  11.326+	
  11.327+	switch(sigalg & 0xFF){
  11.328+	case 0x01:
  11.329+		rsapk = X509toRSApub(c->cert->data, c->cert->len, nil, 0);
  11.330+		if(rsapk == nil)
  11.331+			return "bad certificate";
  11.332+		err = X509rsaverifydigest(sig->data, sig->len, digest, digestlen, rsapk);
  11.333+		rsapubfree(rsapk);
  11.334+		break;
  11.335+	case 0x03:
  11.336+		ecpk = X509toECpub(c->cert->data, c->cert->len, &dom);
  11.337+		if(ecpk == nil)
  11.338+			return "bad certificate";
  11.339+		err = X509ecdsaverifydigest(sig->data, sig->len, digest, digestlen, &dom, ecpk);
  11.340+		ecdomfree(&dom);
  11.341+		ecpubfree(ecpk);
  11.342+		break;
  11.343+	default:
  11.344+		err = "signaure algorithm not RSA or ECDSA";
  11.345+	}
  11.346 
  11.347 	return err;
  11.348 }
    12.1--- a/sys/src/libsec/port/x509.c
    12.2+++ b/sys/src/libsec/port/x509.c
    12.3@@ -134,8 +134,7 @@ static int	encode(Elem e, Bytes** pbytes
    12.4 static int	oid_lookup(Ints* o, Ints** tab);
    12.5 static void	freevalfields(Value* v);
    12.6 static mpint	*asn1mpint(Elem *e);
    12.7-
    12.8-
    12.9+static void	edump(Elem);
   12.10 
   12.11 #define TAG_MASK 0x1F
   12.12 #define CONSTR_MASK 0x20
   12.13@@ -223,6 +222,7 @@ ber_decode(uchar** pp, uchar* pend, Elem
   12.14 	Tag tag;
   12.15 	Value val;
   12.16 
   12.17+	memset(pelem, 0, sizeof(*pelem));
   12.18 	err = tag_decode(pp, pend, &tag, &isconstr);
   12.19 	if(err == ASN_OK) {
   12.20 		err = length_decode(pp, pend, &length);
   12.21@@ -1159,21 +1159,8 @@ is_int(Elem* pe, int* pint)
   12.22 static int
   12.23 is_bigint(Elem* pe, Bytes** pbigint)
   12.24 {
   12.25-	int v, n, i;
   12.26-
   12.27-	if(pe->tag.class == Universal && pe->tag.num == INTEGER) {
   12.28-		if(pe->val.tag == VBigInt)
   12.29-			*pbigint = pe->val.u.bigintval;
   12.30-		else if(pe->val.tag == VInt){
   12.31-			v = pe->val.u.intval;
   12.32-			for(n = 1; n < 4; n++)
   12.33-				if((1 << (8 * n)) > v)
   12.34-					break;
   12.35-			*pbigint = newbytes(n);
   12.36-			for(i = 0; i < n; i++)
   12.37-				(*pbigint)->data[i] = (v >> ((n - 1 - i) * 8));
   12.38-		}else
   12.39-			return 0;
   12.40+	if(pe->tag.class == Universal && pe->tag.num == INTEGER && pe->val.tag == VBigInt) {
   12.41+		*pbigint = pe->val.u.bigintval;
   12.42 		return 1;
   12.43 	}
   12.44 	return 0;
   12.45@@ -1536,6 +1523,7 @@ typedef struct CertX509 {
   12.46 	Bytes*	publickey;
   12.47 	int	signature_alg;
   12.48 	Bytes*	signature;
   12.49+	int	curve;
   12.50 } CertX509;
   12.51 
   12.52 /* Algorithm object-ids */
   12.53@@ -1553,6 +1541,12 @@ enum {
   12.54 	ALG_sha512WithRSAEncryption,
   12.55 	ALG_sha224WithRSAEncryption,
   12.56 
   12.57+	ALG_ecPublicKey,
   12.58+	ALG_sha1WithECDSA,
   12.59+	ALG_sha256WithECDSA,
   12.60+	ALG_sha384WithECDSA,
   12.61+	ALG_sha512WithECDSA,
   12.62+
   12.63 	ALG_md5,
   12.64 	ALG_sha1,
   12.65 	ALG_sha256,
   12.66@@ -1587,6 +1581,7 @@ enum {
   12.67 };
   12.68 
   12.69 static Ints15 oid_rsaEncryption = {7, 1, 2, 840, 113549, 1, 1, 1 };
   12.70+
   12.71 static Ints15 oid_md2WithRSAEncryption = {7, 1, 2, 840, 113549, 1, 1, 2 };
   12.72 static Ints15 oid_md4WithRSAEncryption = {7, 1, 2, 840, 113549, 1, 1, 3 };
   12.73 static Ints15 oid_md5WithRSAEncryption = {7, 1, 2, 840, 113549, 1, 1, 4 };
   12.74@@ -1597,6 +1592,12 @@ static Ints15 oid_sha384WithRSAEncryptio
   12.75 static Ints15 oid_sha512WithRSAEncryption = {7, 1, 2, 840, 113549, 1, 1, 13 };
   12.76 static Ints15 oid_sha224WithRSAEncryption = {7, 1, 2, 840, 113549, 1, 1, 14 };
   12.77 
   12.78+static Ints15 oid_ecPublicKey = {6, 1, 2, 840, 10045, 2, 1 };
   12.79+static Ints15 oid_sha1WithECDSA = {6, 1, 2, 840, 10045, 4, 1 };
   12.80+static Ints15 oid_sha256WithECDSA = {7, 1, 2, 840, 10045, 4, 3, 2 };
   12.81+static Ints15 oid_sha384WithECDSA = {7, 1, 2, 840, 10045, 4, 3, 3 };
   12.82+static Ints15 oid_sha512WithECDSA = {7, 1, 2, 840, 10045, 4, 3, 4 };
   12.83+
   12.84 static Ints15 oid_md5 = {6, 1, 2, 840, 113549, 2, 5 };
   12.85 static Ints15 oid_sha1 = {6, 1, 3, 14, 3, 2, 26 };
   12.86 static Ints15 oid_sha256= {9, 2, 16, 840, 1, 101, 3, 4, 2, 1 };
   12.87@@ -1618,6 +1619,12 @@ static Ints *alg_oid_tab[NUMALGS+1] = {
   12.88 	(Ints*)&oid_sha512WithRSAEncryption,
   12.89 	(Ints*)&oid_sha224WithRSAEncryption,
   12.90 
   12.91+	(Ints*)&oid_ecPublicKey,
   12.92+	(Ints*)&oid_sha1WithECDSA,
   12.93+	(Ints*)&oid_sha256WithECDSA,
   12.94+	(Ints*)&oid_sha384WithECDSA,
   12.95+	(Ints*)&oid_sha512WithECDSA,
   12.96+
   12.97 	(Ints*)&oid_md5,
   12.98 	(Ints*)&oid_sha1,
   12.99 	(Ints*)&oid_sha256,
  12.100@@ -1631,10 +1638,22 @@ static DigestAlg *digestalg[NUMALGS+1] =
  12.101 	&alg_md5, &alg_md5, &alg_md5, &alg_md5,
  12.102 	&alg_sha1, &alg_sha1,
  12.103 	&alg_sha256, &alg_sha384, &alg_sha512, &alg_sha224,
  12.104+	&alg_sha256, &alg_sha1, &alg_sha256, &alg_sha384, &alg_sha512,
  12.105 	&alg_md5, &alg_sha1, &alg_sha256, &alg_sha384, &alg_sha512, &alg_sha224,
  12.106 	nil
  12.107 };
  12.108 
  12.109+static Ints15 oid_secp256r1 = {7, 1, 2, 840, 10045, 3, 1, 7};
  12.110+
  12.111+static Ints *namedcurves_oid_tab[] = {
  12.112+	(Ints*)&oid_secp256r1,
  12.113+	nil,
  12.114+};
  12.115+static void (*namedcurves[])(mpint *p, mpint *a, mpint *b, mpint *x, mpint *y, mpint *n, mpint *h) = {
  12.116+	secp256r1,
  12.117+	nil,
  12.118+};
  12.119+
  12.120 static void
  12.121 freecert(CertX509* c)
  12.122 {
  12.123@@ -1726,6 +1745,17 @@ parse_alg(Elem* e)
  12.124 	return oid_lookup(oid, alg_oid_tab);
  12.125 }
  12.126 
  12.127+static int
  12.128+parse_curve(Elem* e)
  12.129+{
  12.130+	Elist* el;
  12.131+	Ints* oid;
  12.132+
  12.133+	if(!is_seq(e, &el) || elistlen(el)<2 || !is_oid(&el->tl->hd, &oid))
  12.134+		return -1;
  12.135+	return oid_lookup(oid, namedcurves_oid_tab);
  12.136+}
  12.137+
  12.138 static CertX509*
  12.139 decode_cert(Bytes* a)
  12.140 {
  12.141@@ -1828,7 +1858,7 @@ decode_cert(Bytes* a)
  12.142 		goto errret;
  12.143 
  12.144 	/* SubjectPublicKeyInfo */
  12.145- 	if(!is_seq(epubkey, &elpubkey))
  12.146+	if(!is_seq(epubkey, &elpubkey))
  12.147 		goto errret;
  12.148 	if(elistlen(elpubkey) != 2)
  12.149 		goto errret;
  12.150@@ -1836,6 +1866,12 @@ decode_cert(Bytes* a)
  12.151 	c->publickey_alg = parse_alg(&elpubkey->hd);
  12.152 	if(c->publickey_alg < 0)
  12.153 		goto errret;
  12.154+	c->curve = -1;
  12.155+	if(c->publickey_alg == ALG_ecPublicKey){
  12.156+		c->curve = parse_curve(&elpubkey->hd);
  12.157+		if(c->curve < 0)
  12.158+			goto errret;
  12.159+	}
  12.160   	if(!is_bitstring(&elpubkey->tl->hd, &bits))
  12.161 		goto errret;
  12.162 	if(bits->unusedbits != 0)
  12.163@@ -1869,32 +1905,23 @@ static RSApub*
  12.164 decode_rsapubkey(Bytes* a)
  12.165 {
  12.166 	Elem e;
  12.167-	Elist *el, *l;
  12.168-	mpint *mp;
  12.169+	Elist *el;
  12.170 	RSApub* key;
  12.171 
  12.172-	l = nil;
  12.173 	key = rsapuballoc();
  12.174 	if(decode(a->data, a->len, &e) != ASN_OK)
  12.175 		goto errret;
  12.176 	if(!is_seq(&e, &el) || elistlen(el) != 2)
  12.177 		goto errret;
  12.178-
  12.179-	l = el;
  12.180-
  12.181-	key->n = mp = asn1mpint(&el->hd);
  12.182-	if(mp == nil)
  12.183+	if((key->n = asn1mpint(&el->hd)) == nil)
  12.184 		goto errret;
  12.185-
  12.186 	el = el->tl;
  12.187-	key->ek = mp = asn1mpint(&el->hd);
  12.188-	if(mp == nil)
  12.189+	if((key->ek = asn1mpint(&el->hd)) == nil)
  12.190 		goto errret;
  12.191-
  12.192-	freeelist(l);
  12.193+	freevalfields(&e.val);
  12.194 	return key;
  12.195 errret:
  12.196-	freeelist(l);
  12.197+	freevalfields(&e.val);
  12.198 	rsapubfree(key);
  12.199 	return nil;
  12.200 }
  12.201@@ -1917,7 +1944,6 @@ decode_rsaprivkey(Bytes* a)
  12.202 	int version;
  12.203 	Elem e;
  12.204 	Elist *el;
  12.205-	mpint *mp;
  12.206 	RSApriv* key;
  12.207 
  12.208 	key = rsaprivalloc();
  12.209@@ -1929,47 +1955,41 @@ decode_rsaprivkey(Bytes* a)
  12.210 		goto errret;
  12.211 
  12.212 	el = el->tl;
  12.213-	key->pub.n = mp = asn1mpint(&el->hd);
  12.214-	if(mp == nil)
  12.215+	if((key->pub.n = asn1mpint(&el->hd)) == nil)
  12.216 		goto errret;
  12.217 
  12.218 	el = el->tl;
  12.219-	key->pub.ek = mp = asn1mpint(&el->hd);
  12.220-	if(mp == nil)
  12.221+	if((key->pub.ek = asn1mpint(&el->hd)) == nil)
  12.222 		goto errret;
  12.223 
  12.224 	el = el->tl;
  12.225-	key->dk = mp = asn1mpint(&el->hd);
  12.226-	if(mp == nil)
  12.227+	if((key->dk = asn1mpint(&el->hd)) == nil)
  12.228 		goto errret;
  12.229 
  12.230 	el = el->tl;
  12.231-	key->q = mp = asn1mpint(&el->hd);
  12.232-	if(mp == nil)
  12.233+	if((key->q = asn1mpint(&el->hd)) == nil)
  12.234 		goto errret;
  12.235 
  12.236 	el = el->tl;
  12.237-	key->p = mp = asn1mpint(&el->hd);
  12.238-	if(mp == nil)
  12.239+	if((key->p = asn1mpint(&el->hd)) == nil)
  12.240 		goto errret;
  12.241 
  12.242 	el = el->tl;
  12.243-	key->kq = mp = asn1mpint(&el->hd);
  12.244-	if(mp == nil)
  12.245+	if((key->kq = asn1mpint(&el->hd)) == nil)
  12.246 		goto errret;
  12.247 
  12.248 	el = el->tl;
  12.249-	key->kp = mp = asn1mpint(&el->hd);
  12.250-	if(mp == nil)
  12.251+	if((key->kp = asn1mpint(&el->hd)) == nil)
  12.252 		goto errret;
  12.253 
  12.254 	el = el->tl;
  12.255-	key->c2 = mp = asn1mpint(&el->hd);
  12.256-	if(mp == nil)
  12.257+	if((key->c2 = asn1mpint(&el->hd)) == nil)
  12.258 		goto errret;
  12.259 
  12.260+	freevalfields(&e.val);
  12.261 	return key;
  12.262 errret:
  12.263+	freevalfields(&e.val);
  12.264 	rsaprivfree(key);
  12.265 	return nil;
  12.266 }
  12.267@@ -1990,7 +2010,6 @@ decode_dsaprivkey(Bytes* a)
  12.268 	int version;
  12.269 	Elem e;
  12.270 	Elist *el;
  12.271-	mpint *mp;
  12.272 	DSApriv* key;
  12.273 
  12.274 	key = dsaprivalloc();
  12.275@@ -2003,32 +2022,29 @@ decode_dsaprivkey(Bytes* a)
  12.276 		goto errret;
  12.277 
  12.278 	el = el->tl;
  12.279-	key->pub.p = mp = asn1mpint(&el->hd);
  12.280-	if(mp == nil)
  12.281+	if((key->pub.p = asn1mpint(&el->hd)) == nil)
  12.282 		goto errret;
  12.283 
  12.284 	el = el->tl;
  12.285-	key->pub.q = mp = asn1mpint(&el->hd);
  12.286-	if(mp == nil)
  12.287+	if((key->pub.q = asn1mpint(&el->hd)) == nil)
  12.288+		goto errret;
  12.289+
  12.290+	el = el->tl;
  12.291+	if((key->pub.alpha = asn1mpint(&el->hd)) == nil)
  12.292 		goto errret;
  12.293 
  12.294 	el = el->tl;
  12.295-	key->pub.alpha = mp = asn1mpint(&el->hd);
  12.296-	if(mp == nil)
  12.297+	if((key->pub.key = asn1mpint(&el->hd)) == nil)
  12.298 		goto errret;
  12.299 
  12.300 	el = el->tl;
  12.301-	key->pub.key = mp = asn1mpint(&el->hd);
  12.302-	if(mp == nil)
  12.303+	if((key->secret = asn1mpint(&el->hd)) == nil)
  12.304 		goto errret;
  12.305 
  12.306-	el = el->tl;
  12.307-	key->secret = mp = asn1mpint(&el->hd);
  12.308-	if(mp == nil)
  12.309-		goto errret;
  12.310-
  12.311+	freevalfields(&e.val);
  12.312 	return key;
  12.313 errret:
  12.314+	freevalfields(&e.val);
  12.315 	dsaprivfree(key);
  12.316 	return nil;
  12.317 }
  12.318@@ -2037,16 +2053,12 @@ static mpint*
  12.319 asn1mpint(Elem *e)
  12.320 {
  12.321 	Bytes *b;
  12.322-	mpint *mp;
  12.323 	int v;
  12.324 
  12.325 	if(is_int(e, &v))
  12.326 		return itomp(v, nil);
  12.327-	if(is_bigint(e, &b)) {
  12.328-		mp = betomp(b->data, b->len, nil);
  12.329-		freebytes(b);
  12.330-		return mp;
  12.331-	}
  12.332+	if(is_bigint(e, &b))
  12.333+		return betomp(b->data, b->len, nil);
  12.334 	return nil;
  12.335 }
  12.336 
  12.337@@ -2134,7 +2146,7 @@ digest_certinfo(Bytes *cert, DigestAlg *
  12.338 	return da->len;
  12.339 }
  12.340 
  12.341-int
  12.342+static int
  12.343 pkcs1decryptsignature(uchar *sig, int siglen, RSApub *pk, uchar **pbuf)
  12.344 {
  12.345 	int nlen, buflen;
  12.346@@ -2169,34 +2181,41 @@ bad:
  12.347 	return -1;
  12.348 }
  12.349 
  12.350-static char*
  12.351-verify_digestinfo(uchar *sig, int siglen, RSApub *pk, uchar *pdigest, int *psigalg)
  12.352+char*
  12.353+X509rsaverifydigest(uchar *sig, int siglen, uchar *edigest, int edigestlen, RSApub *pk)
  12.354 {
  12.355 	Elem e;
  12.356 	Elist *el;
  12.357 	Bytes *digest;
  12.358 	uchar *buf;
  12.359-	int buflen;
  12.360+	int alg, buflen;
  12.361 	char *err;
  12.362 
  12.363+	buflen = pkcs1decryptsignature(sig, siglen, pk, &buf);
  12.364+	if(buflen == edigestlen && tsmemcmp(buf, edigest, edigestlen) == 0){
  12.365+		free(buf);
  12.366+		return nil;
  12.367+	}
  12.368 	el = nil;
  12.369 	memset(&e, 0, sizeof(e));
  12.370-	buflen = pkcs1decryptsignature(sig, siglen, pk, &buf);
  12.371 	if(buflen < 0 || decode(buf, buflen, &e) != ASN_OK
  12.372 	|| !is_seq(&e, &el) || elistlen(el) != 2 || !is_octetstring(&el->tl->hd, &digest)) {
  12.373 		err = "signature parse error";
  12.374 		goto end;
  12.375 	}
  12.376-	*psigalg = parse_alg(&el->hd);
  12.377-	if(*psigalg < 0){
  12.378+	alg = parse_alg(&el->hd);
  12.379+	if(alg < 0){
  12.380 		err = "unknown signature algorithm";
  12.381 		goto end;
  12.382 	}
  12.383-	if(digest->len != digestalg[*psigalg]->len){
  12.384+	if(digest->len != edigestlen || digest->len != digestalg[alg]->len){
  12.385 		err = "bad digest length";
  12.386 		goto end;
  12.387 	}
  12.388-	memmove(pdigest, digest->data, digest->len);
  12.389+	if(tsmemcmp(digest->data, edigest, edigestlen) != 0){
  12.390+		err = "digest did not match";
  12.391+		goto end;
  12.392+	}
  12.393 	err = nil;
  12.394 end:
  12.395 	freevalfields(&e.val);
  12.396@@ -2205,64 +2224,60 @@ end:
  12.397 }
  12.398 
  12.399 char*
  12.400-X509verifydigest(uchar *sig, int siglen, uchar *edigest, int edigestlen, RSApub *pk)
  12.401+X509ecdsaverifydigest(uchar *sig, int siglen, uchar *edigest, int edigestlen, ECdomain *dom, ECpub *pub)
  12.402 {
  12.403-	uchar digest[MAXdlen];
  12.404-	int sigalg;
  12.405-	char *e;
  12.406+	Elem e;
  12.407+	Elist *el;
  12.408+	mpint *r, *s;
  12.409+	char *err;
  12.410 
  12.411-	e = verify_digestinfo(sig, siglen, pk, digest, &sigalg);
  12.412-	if(e != nil)
  12.413-		return e;
  12.414-	if(digestalg[sigalg]->len != edigestlen)
  12.415-		return "bad digest length";
  12.416-	if(tsmemcmp(digest, edigest, edigestlen) != 0)
  12.417-		return "digests did not match";
  12.418-	return nil;
  12.419+	r = s = nil;
  12.420+	err = "bad signature";
  12.421+	if(decode(sig, siglen, &e) != ASN_OK)
  12.422+		goto end;
  12.423+	if(!is_seq(&e, &el) || elistlen(el) != 2)
  12.424+		goto end;
  12.425+	r = asn1mpint(&el->hd);
  12.426+	if(r == nil)
  12.427+		goto end;
  12.428+	el = el->tl;
  12.429+	s = asn1mpint(&el->hd);
  12.430+	if(s == nil)
  12.431+		goto end;
  12.432+	if(ecdsaverify(dom, pub, edigest, edigestlen, r, s))
  12.433+		err = nil;
  12.434+end:
  12.435+	freevalfields(&e.val);
  12.436+	mpfree(s);
  12.437+	mpfree(r);
  12.438+	return err;
  12.439 }
  12.440 
  12.441-char*
  12.442-X509verifydata(uchar *sig, int siglen, uchar *data, int datalen, RSApub *pk)
  12.443+ECpub*
  12.444+X509toECpub(uchar *cert, int ncert, ECdomain *dom)
  12.445 {
  12.446-	uchar digest[MAXdlen], edigest[MAXdlen];
  12.447-	int sigalg;
  12.448-	char *e;
  12.449-
  12.450-	e = verify_digestinfo(sig, siglen, pk, digest, &sigalg);
  12.451-	if(e != nil)
  12.452-		return e;
  12.453-	(*digestalg[sigalg]->fun)(data, datalen, edigest, nil);
  12.454-	if(tsmemcmp(digest, edigest, digestalg[sigalg]->len) != 0)
  12.455-		return "digests did not match";
  12.456-	return nil;
  12.457-}
  12.458-
  12.459-RSApub*
  12.460-X509toRSApub(uchar *cert, int ncert, char *name, int nname)
  12.461-{
  12.462-	char *e;
  12.463+	CertX509 *c;
  12.464+	ECpub *pub;
  12.465 	Bytes *b;
  12.466-	CertX509 *c;
  12.467-	RSApub *pk;
  12.468 
  12.469 	b = makebytes(cert, ncert);
  12.470 	c = decode_cert(b);
  12.471 	freebytes(b);
  12.472 	if(c == nil)
  12.473 		return nil;
  12.474-	if(name != nil && c->subject != nil){
  12.475-		e = strchr(c->subject, ',');
  12.476-		if(e != nil)
  12.477-			*e = 0;	/* take just CN part of Distinguished Name */
  12.478-		strncpy(name, c->subject, nname);
  12.479+	pub = nil;
  12.480+	if(c->publickey_alg == ALG_ecPublicKey){
  12.481+		ecdominit(dom, namedcurves[c->curve]);
  12.482+		pub = ecdecodepub(dom, c->publickey->data, c->publickey->len);
  12.483+		if(pub == nil)
  12.484+			ecdomfree(dom);
  12.485 	}
  12.486-	pk = decode_rsapubkey(c->publickey);
  12.487 	freecert(c);
  12.488-	return pk;
  12.489+	return pub;
  12.490 }
  12.491 
  12.492 char*
  12.493-X509verify(uchar *cert, int ncert, RSApub *pk)
  12.494+X509ecdsaverify(uchar *cert, int ncert, ECdomain *dom, ECpub *pk)
  12.495 {
  12.496 	char *e;
  12.497 	Bytes *b;
  12.498@@ -2282,7 +2297,59 @@ X509verify(uchar *cert, int ncert, RSApu
  12.499 		freecert(c);
  12.500 		return "cannot decode certinfo";
  12.501 	}
  12.502-	e = X509verifydigest(c->signature->data, c->signature->len, digest, digestlen, pk);
  12.503+	e = X509ecdsaverifydigest(c->signature->data, c->signature->len, digest, digestlen, dom, pk);
  12.504+	freecert(c);
  12.505+	return e;
  12.506+}
  12.507+
  12.508+RSApub*
  12.509+X509toRSApub(uchar *cert, int ncert, char *name, int nname)
  12.510+{
  12.511+	char *e;
  12.512+	Bytes *b;
  12.513+	CertX509 *c;
  12.514+	RSApub *pub;
  12.515+
  12.516+	b = makebytes(cert, ncert);
  12.517+	c = decode_cert(b);
  12.518+	freebytes(b);
  12.519+	if(c == nil)
  12.520+		return nil;
  12.521+	if(name != nil && c->subject != nil){
  12.522+		e = strchr(c->subject, ',');
  12.523+		if(e != nil)
  12.524+			*e = 0;	/* take just CN part of Distinguished Name */
  12.525+		strncpy(name, c->subject, nname);
  12.526+	}
  12.527+	pub = nil;
  12.528+	if(c->publickey_alg == ALG_rsaEncryption)
  12.529+		pub = decode_rsapubkey(c->publickey);
  12.530+	freecert(c);
  12.531+	return pub;
  12.532+}
  12.533+
  12.534+char*
  12.535+X509rsaverify(uchar *cert, int ncert, RSApub *pk)
  12.536+{
  12.537+	char *e;
  12.538+	Bytes *b;
  12.539+	CertX509 *c;
  12.540+	int digestlen;
  12.541+	uchar digest[MAXdlen];
  12.542+
  12.543+	b = makebytes(cert, ncert);
  12.544+	c = decode_cert(b);
  12.545+	if(c == nil){
  12.546+		freebytes(b);
  12.547+		return "cannot decode cert";
  12.548+	}
  12.549+	digestlen = digest_certinfo(b, digestalg[c->signature_alg], digest);
  12.550+	freebytes(b);
  12.551+	if(digestlen <= 0){
  12.552+		freecert(c);
  12.553+		return "cannot decode certinfo";
  12.554+	}
  12.555+	e = X509rsaverifydigest(c->signature->data, c->signature->len, digest, digestlen, pk);
  12.556 	freecert(c);
  12.557 	return e;
  12.558 }
  12.559@@ -2512,7 +2579,7 @@ X509encodesignature_sha256(uchar digest[
  12.560 }
  12.561 
  12.562 uchar*
  12.563-X509gen(RSApriv *priv, char *subj, ulong valid[2], int *certlen)
  12.564+X509rsagen(RSApriv *priv, char *subj, ulong valid[2], int *certlen)
  12.565 {
  12.566 	int serial = 0, sigalg = ALG_sha256WithRSAEncryption;
  12.567 	uchar *cert = nil;
  12.568@@ -2583,7 +2650,7 @@ errret:
  12.569 }
  12.570 
  12.571 uchar*
  12.572-X509req(RSApriv *priv, char *subj, int *certlen)
  12.573+X509rsareq(RSApriv *priv, char *subj, int *certlen)
  12.574 {
  12.575 	/* RFC 2314, PKCS #10 Certification Request Syntax */
  12.576 	int version = 0, sigalg = ALG_sha256WithRSAEncryption;
  12.577@@ -2738,7 +2805,9 @@ X509dump(uchar *cert, int ncert)
  12.578 	char *e;
  12.579 	Bytes *b;
  12.580 	CertX509 *c;
  12.581-	RSApub *pk;
  12.582+	RSApub *rsapub;
  12.583+	ECpub *ecpub;
  12.584+	ECdomain ecdom;
  12.585 	int digestlen;
  12.586 	uchar digest[MAXdlen];
  12.587 
  12.588@@ -2762,16 +2831,36 @@ X509dump(uchar *cert, int ncert)
  12.589 	print("issuer %s\n", c->issuer);
  12.590 	print("validity %s %s\n", c->validity_start, c->validity_end);
  12.591 	print("subject %s\n", c->subject);
  12.592-	pk = decode_rsapubkey(c->publickey);
  12.593-	print("pubkey e=%B n(%d)=%B\n", pk->ek, mpsignif(pk->n), pk->n);
  12.594 
  12.595 	print("sigalg=%d digest=%.*H\n", c->signature_alg, digestlen, digest);
  12.596-	e = X509verifydigest(c->signature->data, c->signature->len, digest, digestlen, pk);
  12.597-	if(e==nil)
  12.598-		e = "nil (meaning ok)";
  12.599-	print("self-signed X509verifydigest returns: %s\n", e);
  12.600+	print("publickey_alg=%d pubkey[%d] %.*H\n", c->publickey_alg, c->publickey->len,
  12.601+		c->publickey->len, c->publickey->data);
  12.602 
  12.603-	rsapubfree(pk);
  12.604+	switch(c->publickey_alg){
  12.605+	case ALG_rsaEncryption:
  12.606+		rsapub = decode_rsapubkey(c->publickey);
  12.607+		if(rsapub != nil){
  12.608+			print("rsa pubkey e=%B n(%d)=%B\n", rsapub->ek, mpsignif(rsapub->n), rsapub->n);
  12.609+			e = X509rsaverifydigest(c->signature->data, c->signature->len, digest, digestlen, rsapub);
  12.610+			if(e==nil)
  12.611+				e = "nil (meaning ok)";
  12.612+			print("self-signed X509rsaverifydigest returns: %s\n", e);
  12.613+			rsapubfree(rsapub);
  12.614+		}
  12.615+		break;
  12.616+	case ALG_ecPublicKey:
  12.617+		ecdominit(&ecdom, namedcurves[c->curve]);
  12.618+		ecpub = ecdecodepub(&ecdom, c->publickey->data, c->publickey->len);
  12.619+		if(ecpub != nil){
  12.620+			e = X509ecdsaverifydigest(c->signature->data, c->signature->len, digest, digestlen, &ecdom, ecpub);
  12.621+			if(e==nil)
  12.622+				e = "nil (meaning ok)";
  12.623+			print("self-signed X509ecdsaverifydigest returns: %s\n", e);
  12.624+			ecpubfree(ecpub);
  12.625+		}
  12.626+		ecdomfree(&ecdom);
  12.627+		break;
  12.628+	}
  12.629 	freecert(c);
  12.630 	print("end X509dump\n");
  12.631 }