shithub: riscv

Download patch

ref: 8a67560183b3b726c827bcac02632b2b8e3ba59d
parent: 5f42da15355e3548634b778271251e7d078f01e6
author: cinap_lenrek <[email protected]>
date: Fri Oct 6 16:52:18 EDT 2017

libsec: export asn1encodedigest(), asn1encodeRSApub(), asn1toRSApub(), pkcs1padbuf() and pkcs1unpadbuf()

--- a/sys/include/libsec.h
+++ b/sys/include/libsec.h
@@ -355,6 +355,7 @@
 void		rsaprivfree(RSApriv*);
 RSApub*		rsaprivtopub(RSApriv*);
 RSApub*		X509toRSApub(uchar*, int, char*, int);
+RSApub*		asn1toRSApub(uchar*, int);
 RSApriv*	asn1toRSApriv(uchar*, int);
 void		asn1dump(uchar *der, int len);
 uchar*		decodePEM(char *s, char *type, int *len, char **new_s);
@@ -365,6 +366,13 @@
 char*		X509rsaverifydigest(uchar *sig, int siglen, uchar *edigest, int edigestlen, RSApub *pk);
 
 void		X509dump(uchar *cert, int ncert);
+
+mpint*		pkcs1padbuf(uchar *buf, int len, mpint *modulus, int blocktype);
+int		pkcs1unpadbuf(uchar *buf, int len, mpint *modulus, int blocktype);
+int		asn1encodeRSApub(RSApub *pk, uchar *buf, int len);
+int		asn1encodedigest(DigestState* (*fun)(uchar*, ulong, uchar*, DigestState*),
+			uchar *digest, uchar *buf, int len);
+
 
 /*
  * elgamal
--- a/sys/src/libsec/port/tlshand.c
+++ b/sys/src/libsec/port/tlshand.c
@@ -445,11 +445,6 @@
 static void freeints(Ints* b);
 static int lookupid(Ints* b, int id);
 
-/* x509.c */
-extern mpint*	pkcs1padbuf(uchar *buf, int len, mpint *modulus, int blocktype);
-extern int	pkcs1unpadbuf(uchar *buf, int len, mpint *modulus, int blocktype);
-extern int	asn1encodedigest(DigestState* (*fun)(uchar*, ulong, uchar*, DigestState*), uchar *digest, uchar *buf, int len);
-
 //================= client/server ========================
 
 //	push TLS onto fd, returning new (application) file descriptor
--- a/sys/src/libsec/port/x509.c
+++ b/sys/src/libsec/port/x509.c
@@ -1971,8 +1971,8 @@
  *		publicExponent INTEGER
  *	}
  */
-static RSApub*
-decode_rsapubkey(Bytes* a)
+RSApub*
+asn1toRSApub(uchar *buf, int len)
 {
 	Elem e;
 	Elist *el;
@@ -1979,7 +1979,7 @@
 	RSApub* key;
 
 	key = nil;
-	if(decode(a->data, a->len, &e) != ASN_OK)
+	if(decode(buf, len, &e) != ASN_OK)
 		goto errret;
 	if(!is_seq(&e, &el) || elistlen(el) != 2)
 		goto errret;
@@ -1997,8 +1997,15 @@
 	freevalfields(&e.val);
 	rsapubfree(key);
 	return nil;
+
 }
 
+static RSApub*
+decode_rsapubkey(Bytes* a)
+{
+	return asn1toRSApub(a->data, a->len);
+}
+
 /*
  *	RSAPrivateKey ::= SEQUENCE {
  *		version Version,
@@ -2777,12 +2784,40 @@
 	return nil;
 }
 
+static Bytes*
+encode_rsapubkey(RSApub *pk)
+{
+	Bytes *b = nil;
+	Elem e = mkseq(
+		mkel(mkbigint(pk->n),
+		mkel(mpsignif(pk->ek)<32 ? mkint(mptoi(pk->ek)) : mkbigint(pk->ek),
+		nil)));
+	encode(e, &b);
+	freevalfields(&e.val);
+	return b;
+}
+
+int
+asn1encodeRSApub(RSApub *pk, uchar *buf, int len)
+{
+	Bytes *b = encode_rsapubkey(pk);
+	if(b == nil)
+		return -1;
+	if(b->len > len){
+		freebytes(b);
+		werrstr("buffer too small");
+		return -1;
+	}
+	memmove(buf, b->data, len = b->len);
+	freebytes(b);
+	return len;
+}
+
 uchar*
 X509rsagen(RSApriv *priv, char *subj, ulong valid[2], int *certlen)
 {
 	int serial = 0, sigalg = ALG_sha256WithRSAEncryption;
 	uchar *cert = nil;
-	RSApub *pk = rsaprivtopub(priv);
 	Bytes *certbytes, *pkbytes, *certinfobytes, *sigbytes;
 	Elem e, certinfo;
 	DigestAlg *da;
@@ -2791,14 +2826,12 @@
 	mpint *pkcs1;
 	char *alts;
 
+	if((pkbytes = encode_rsapubkey(&priv->pub)) == nil)
+		return nil;
+
 	subj = estrdup(subj);
 	alts = splitalts(subj);
 
-	e = mkseq(mkel(mkbigint(pk->n),mkel(mkint(mptoi(pk->ek)),nil)));
-	if(encode(e, &pkbytes) != ASN_OK)
-		goto errret;
-	freevalfields(&e.val);
-
 	e = mkseq(
 		mkel(mkcont(mkint(2), 0),
 		mkel(mkint(serial),
@@ -2826,7 +2859,7 @@
 	sigbytes = encode_digest(da, digest);
 	if(sigbytes == nil)
 		goto errret;
-	pkcs1 = pkcs1padbuf(sigbytes->data, sigbytes->len, pk->n, 1);
+	pkcs1 = pkcs1padbuf(sigbytes->data, sigbytes->len, priv->pub.n, 1);
 	freebytes(sigbytes);
 	if(pkcs1 == nil)
 		goto errret;
@@ -2860,7 +2893,6 @@
 	/* RFC 2314, PKCS #10 Certification Request Syntax */
 	int version = 0, sigalg = ALG_sha256WithRSAEncryption;
 	uchar *cert = nil;
-	RSApub *pk = rsaprivtopub(priv);
 	Bytes *certbytes, *pkbytes, *certinfobytes, *sigbytes;
 	Elem e, certinfo;
 	DigestAlg *da;
@@ -2869,13 +2901,12 @@
 	mpint *pkcs1;
 	char *alts;
 
+	if((pkbytes = encode_rsapubkey(&priv->pub)) == nil)
+		return nil;
+
 	subj = estrdup(subj);
 	alts = splitalts(subj);
 
-	e = mkseq(mkel(mkbigint(pk->n),mkel(mkint(mptoi(pk->ek)),nil)));
-	if(encode(e, &pkbytes) != ASN_OK)
-		goto errret;
-	freevalfields(&e.val);
 	e = mkseq(
 		mkel(mkint(version),
 		mkel(mkDN(subj),
@@ -2895,7 +2926,7 @@
 	sigbytes = encode_digest(da, digest);
 	if(sigbytes == nil)
 		goto errret;
-	pkcs1 = pkcs1padbuf(sigbytes->data, sigbytes->len, pk->n, 1);
+	pkcs1 = pkcs1padbuf(sigbytes->data, sigbytes->len, priv->pub.n, 1);
 	freebytes(sigbytes);
 	if(pkcs1 == nil)
 		goto errret;