Browse Source

Plan 9 from Bell Labs 2003-03-12

David du Colombier 21 years ago
parent
commit
82d2b03358
3 changed files with 129 additions and 18 deletions
  1. 1 1
      dist/replica/plan9.db
  2. 2 0
      dist/replica/plan9.log
  3. 126 17
      sys/src/libsec/port/x509.c

+ 1 - 1
dist/replica/plan9.db

@@ -11704,7 +11704,7 @@ sys/src/libsec/port/smallprimes.c - 664 sys sys 984710525 6851
 sys/src/libsec/port/smallprimetest.c - 664 sys sys 984710525 70640
 sys/src/libsec/port/thumb.c - 664 sys sys 1019832052 1891
 sys/src/libsec/port/tlshand.c - 664 sys sys 1027629126 53465
-sys/src/libsec/port/x509.c - 664 sys sys 1037572311 47543
+sys/src/libsec/port/x509.c - 664 sys sys 1047404307 50237
 sys/src/libsec/power - 20000000775 sys sys 984710502 0
 sys/src/libsec/power/mkfile - 664 sys sys 1032061453 139
 sys/src/libstdio - 20000000775 sys sys 984710098 0

+ 2 - 0
dist/replica/plan9.log

@@ -18566,3 +18566,5 @@
 1047299416 0 c sys/src/9/bitsy/wavelan.c - 664 sys sys 1047298972 27107
 1047308424 0 c 386/bin/aux/p9bitpost - 775 sys sys 1047307246 128070
 1047322832 0 d sys/src/9/boot/libboot.a8 - 664 sys sys 1047260766 0
+1047403889 0 c sys/src/libsec/port/x509.c - 664 sys sys 1047403870 50248
+1047405689 0 c sys/src/libsec/port/x509.c - 664 sys sys 1047404307 50237

+ 126 - 17
sys/src/libsec/port/x509.c

@@ -1573,6 +1573,7 @@ enum {
 	ALG_md4WithRSAEncryption,
 	ALG_md5WithRSAEncryption,
 	ALG_sha1WithRSAEncryption,
+	ALG_md5,
 	NUMALGS
 };
 typedef struct Ints7 {
@@ -1584,15 +1585,17 @@ static Ints7 oid_md2WithRSAEncryption = {7, 1, 2, 840, 113549, 1, 1, 2 };
 static Ints7 oid_md4WithRSAEncryption = {7, 1, 2, 840, 113549, 1, 1, 3 };
 static Ints7 oid_md5WithRSAEncryption = {7, 1, 2, 840, 113549, 1, 1, 4 };
 static Ints7 oid_sha1WithRSAEncryption ={7, 1, 2, 840, 113549, 1, 1, 5 };
+static Ints7 oid_md5 ={6, 1, 2, 840, 113549, 2, 5, 0 };
 static Ints *alg_oid_tab[NUMALGS+1] = {
 	(Ints*)&oid_rsaEncryption,
 	(Ints*)&oid_md2WithRSAEncryption,
 	(Ints*)&oid_md4WithRSAEncryption,
 	(Ints*)&oid_md5WithRSAEncryption,
 	(Ints*)&oid_sha1WithRSAEncryption,
+	(Ints*)&oid_md5,
 	nil
 };
-static DigestFun digestalg[NUMALGS+1] = { md5, md5, md5, md5, sha1, nil };
+static DigestFun digestalg[NUMALGS+1] = { md5, md5, md5, md5, sha1, md5, nil };
 
 static void
 freecert(CertX509* c)
@@ -2008,7 +2011,7 @@ digest_certinfo(Bytes *cert, DigestFun digestfun, uchar *digest)
 }
 
 static char*
-verify_signature(Bytes* signature, RSApub *pk, uchar *edigest)
+verify_signature(Bytes* signature, RSApub *pk, uchar *edigest, Elem **psigalg)
 {
 	Elem e;
 	Elist *el;
@@ -2034,6 +2037,7 @@ verify_signature(Bytes* signature, RSApub *pk, uchar *edigest)
 	if(decode(buf, buflen, &e) != ASN_OK || !is_seq(&e, &el) || elistlen(el) != 2 ||
 			!is_octetstring(&el->tl->hd, &digest))
 		return "signature parse error";
+	*psigalg = &el->hd;
 	if(memcmp(digest->data, edigest, digest->len) == 0)
 		return nil;
 	return "digests did not match";
@@ -2070,6 +2074,7 @@ X509verify(uchar *cert, int ncert, RSApub *pk)
 	Bytes *b;
 	CertX509 *c;
 	uchar digest[SHA1dlen];
+	Elem *sigalg;
 
 	b = makebytes(cert, ncert);
 	c = decode_cert(b);
@@ -2077,8 +2082,8 @@ X509verify(uchar *cert, int ncert, RSApub *pk)
 		digest_certinfo(b, digestalg[c->signature_alg], digest);
 	freebytes(b);
 	if(c == nil)
-		return nil;
-	e = verify_signature(c->signature, pk, digest);
+		return "cannot decode cert";
+	e = verify_signature(c->signature, pk, digest, &sigalg);
 	freecert(c);
 	return e;
 }
@@ -2217,22 +2222,23 @@ mkalg(int alg)
 	return mkseq(mkel(mkoid(alg_oid_tab[alg]), mkel(Null(), nil)));
 }
 
-typedef struct Ints4pref {
+typedef struct Ints7pref {
 	int		len;
-	int		data[4];
+	int		data[7];
 	char	prefix[4];
-} Ints4pref;
-Ints4pref DN_oid[] = {
-	{4, 2, 5, 4, 6,  "C="},
-	{4, 2, 5, 4, 8,  "ST="},
-	{4, 2, 5, 4, 7,  "L="},
-	{4, 2, 5, 4, 10, "O="},
-	{4, 2, 5, 4, 11, "OU="},
-	{4, 2, 5, 4, 3,  "CN="},
+} Ints7pref;
+Ints7pref DN_oid[] = {
+	{4, 2, 5, 4, 6, 0, 0, 0,  "C="},
+	{4, 2, 5, 4, 8, 0, 0, 0,  "ST="},
+	{4, 2, 5, 4, 7, 0, 0, 0,  "L="},
+	{4, 2, 5, 4, 10, 0, 0, 0, "O="},
+	{4, 2, 5, 4, 11, 0, 0, 0, "OU="},
+	{4, 2, 5, 4, 3, 0, 0, 0,  "CN="},
+ 	{7, 1,2,840,113549,1,9,1, "E="},
 };
 
 static Elem
-mkname(Ints4pref *oid, char *subj)
+mkname(Ints7pref *oid, char *subj)
 {
 	return mkset(mkel(mkseq(mkel(mkoid((Ints*)oid), mkel(mkstring(subj), nil))), nil));
 }
@@ -2300,7 +2306,7 @@ X509gen(RSApriv *priv, char *subj, ulong valid[2], int *certlen)
 	md5(certinfobytes->data, certinfobytes->len, digest, 0);
 	freebytes(certinfobytes);
 	sig = mkseq(
-		mkel(mkalg(ALG_md5WithRSAEncryption),
+		mkel(mkalg(ALG_md5),
 		mkel(mkoctet(digest, MD5dlen),
 		nil)));
 	if(encode(sig, &sigbytes) != ASN_OK)
@@ -2326,6 +2332,66 @@ errret:
 	return cert;
 }
 
+uchar*
+X509req(RSApriv *priv, char *subj, int *certlen)
+{
+	/* RFC 2314, PKCS #10 Certification Request Syntax */
+	int version = 0;
+	uchar *cert = nil;
+	RSApub *pk = rsaprivtopub(priv);
+	Bytes *certbytes, *pkbytes, *certinfobytes, *sigbytes;
+	Elem e, certinfo, subject, pubkey, sig;
+	uchar digest[MD5dlen], *buf;
+	int buflen;
+	mpint *pkcs1;
+
+	e.val.tag = VInt;  /* so freevalfields at errret is no-op */
+	subject = mkDN(subj);
+	pubkey = mkseq(mkel(mkbigint(pk->n),mkel(mkint(mptoi(pk->ek)),nil)));
+	if(encode(pubkey, &pkbytes) != ASN_OK)
+		goto errret;
+	freevalfields(&pubkey.val);
+	pubkey = mkseq(
+		mkel(mkalg(ALG_rsaEncryption),
+		mkel(mkbits(pkbytes->data, pkbytes->len),
+		nil)));
+	freebytes(pkbytes);
+	certinfo = mkseq(
+		mkel(mkint(version),
+		mkel(subject,
+		mkel(pubkey,
+		nil))));
+	if(encode(certinfo, &certinfobytes) != ASN_OK)
+		goto errret;
+	md5(certinfobytes->data, certinfobytes->len, digest, 0);
+	freebytes(certinfobytes);
+	sig = mkseq(
+		mkel(mkalg(ALG_md5),
+		mkel(mkoctet(digest, MD5dlen),
+		nil)));
+	if(encode(sig, &sigbytes) != ASN_OK)
+		goto errret;
+	pkcs1 = pkcs1pad(sigbytes, pk->n);
+	freebytes(sigbytes);
+	rsadecrypt(priv, pkcs1, pkcs1);
+	buflen = mptobe(pkcs1, nil, 0, &buf);
+	mpfree(pkcs1);
+	e = mkseq(
+		mkel(certinfo,
+		mkel(mkalg(ALG_md5),
+		mkel(mkbits(buf, buflen),
+		nil))));
+	free(buf);
+	if(encode(e, &certbytes) != ASN_OK)
+		goto errret;
+	if(certlen)
+		*certlen = certbytes->len;
+	cert = certbytes->data;
+errret:
+	freevalfields(&e.val);
+	return cert;
+}
+
 static char*
 tagdump(Tag tag)
 {
@@ -2404,8 +2470,51 @@ asn1dump(uchar *der, int len)
 	Elem e;
 
 	if(decode(der, len, &e) != ASN_OK){
-		fprint(2,"didn't parse\n");
+		print("didn't parse\n");
 		exits("didn't parse");
 	}
 	edump(e);
 }
+
+void
+X509dump(uchar *cert, int ncert)
+{
+	char *e;
+	Bytes *b;
+	CertX509 *c;
+	RSApub *pk;
+	uchar digest[SHA1dlen];
+	Elem *sigalg;
+
+	print("begin X509dump\n");
+	b = makebytes(cert, ncert);
+	c = decode_cert(b);
+	if(c != nil)
+		digest_certinfo(b, digestalg[c->signature_alg], digest);
+	freebytes(b);
+	if(c == nil){
+		print("cannot decode cert");
+		return;
+	}
+
+	print("serial %d\n", c->serial);
+	print("issuer %s\n", c->issuer);
+	print("validity %s %s\n", c->validity_start, c->validity_end);
+	print("subject %s\n", c->subject);
+	pk = decode_rsapubkey(c->publickey);
+	print("pubkey e=%B n(%d)=%B\n", pk->ek, mpsignif(pk->n), pk->n);
+
+	print("sigalg=%d digest=%.*H\n", c->signature_alg, MD5dlen, digest);
+	e = verify_signature(c->signature, pk, digest, &sigalg);
+	if(e==nil){
+		e = "nil (meaning ok)";
+		print("sigalg=\n");
+		if(sigalg)
+			edump(*sigalg);
+	}
+	print("self-signed verify_signature returns: %s\n", e);
+
+	rsapubfree(pk);
+	freecert(c);
+	print("end X509dump\n");
+}