Commit Diff


commit - 039b8c9af0866a5a6607cbdd992b586896d48cdc
commit + 74fc94d47e68684567f16d3d09b822cdad721e4a
blob - a37b64af3fb9f24287f4fbda5c66ef67fd2bab26
blob + f204ca6fbc51343a5a48fff9f28cb7a41665270e
--- src/libsec/port/x509.c
+++ src/libsec/port/x509.c
@@ -1931,6 +1931,68 @@ decode_rsaprivkey(Bytes* a)
 	return key;
 errret:
 	rsaprivfree(key);
+	return nil;
+}
+
+/*
+ * 	DSAPrivateKey ::= SEQUENCE{
+ *		version Version,
+ *		p INTEGER,
+ *		q INTEGER,
+ *		g INTEGER, -- alpha
+ *		pub_key INTEGER, -- key
+ *		priv_key INTEGER, -- secret
+ *	}
+ */
+static DSApriv*
+decode_dsaprivkey(Bytes* a)
+{
+	int version;
+	Elem e;
+	Elist *el;
+	mpint *mp;
+	DSApriv* key;
+
+	key = dsaprivalloc();
+	if(decode(a->data, a->len, &e) != ASN_OK)
+		goto errret;
+	if(!is_seq(&e, &el) || elistlen(el) != 6)
+		goto errret;
+version=-1;
+	if(!is_int(&el->hd, &version) || version != 0)
+{
+fprint(2, "version %d\n", version);
+		goto errret;
+	}
+
+	el = el->tl;
+	key->pub.p = mp = asn1mpint(&el->hd);
+	if(mp == nil)
+		goto errret;
+
+	el = el->tl;
+	key->pub.q = mp = asn1mpint(&el->hd);
+	if(mp == nil)
+		goto errret;
+
+	el = el->tl;
+	key->pub.alpha = mp = asn1mpint(&el->hd);
+	if(mp == nil)
+		goto errret;
+
+	el = el->tl;
+	key->pub.key = mp = asn1mpint(&el->hd);
+	if(mp == nil)
+		goto errret;
+
+	el = el->tl;
+	key->secret = mp = asn1mpint(&el->hd);
+	if(mp == nil)
+		goto errret;
+
+	return key;
+errret:
+	dsaprivfree(key);
 	return nil;
 }
 
@@ -1984,6 +2046,18 @@ asn1toRSApriv(uchar *kd, int kn)
 	return key;
 }
 
+DSApriv*
+asn1toDSApriv(uchar *kd, int kn)
+{
+	Bytes *b;
+	DSApriv *key;
+
+	b = makebytes(kd, kn);
+	key = decode_dsaprivkey(b);
+	freebytes(b);
+	return key;
+}
+
 /*
  * digest(CertificateInfo)
  * Our ASN.1 library doesn't return pointers into the original