ref: 664154893811cc73bfa00ef276776b87070d50f5
parent: 5639f9504be2b325c7c041a59b424880cb9e8cf7
author: cinap_lenrek <[email protected]>
date: Wed Sep 23 13:33:52 EDT 2015
libsec: fix memory leaks in X509req() and X509gen() and return malloced pointer X509req() and X509gen() used to leak memory, and had no way for the caller to free the allocated certificate/certificate request buffer returned. this is not critical as these functions are only used in short lived rsa(2) helper programs. but i prefer to have library routines not leak memory as one does not know in advance where the code is going to be used.
--- a/sys/src/libsec/port/x509.c
+++ b/sys/src/libsec/port/x509.c
@@ -2529,47 +2529,46 @@
uchar *cert = nil;
RSApub *pk = rsaprivtopub(priv);
Bytes *certbytes, *pkbytes, *certinfobytes, *sigbytes;
- Elem e, certinfo, issuer, subject, pubkey, validity, sig;
+ Elem e, certinfo;
DigestAlg *da;
uchar digest[MAXdlen], *buf;
int buflen;
mpint *pkcs1;
- e.val.tag = VInt; /* so freevalfields at errret is no-op */
- issuer = mkDN(subj);
- subject = mkDN(subj);
- pubkey = mkseq(mkel(mkbigint(pk->n),mkel(mkint(mptoi(pk->ek)),nil)));
- if(encode(pubkey, &pkbytes) != ASN_OK)
+ e = mkseq(mkel(mkbigint(pk->n),mkel(mkint(mptoi(pk->ek)),nil)));
+ if(encode(e, &pkbytes) != ASN_OK)
goto errret;
- freevalfields(&pubkey.val);
- pubkey = mkseq(
- mkel(mkalg(ALG_rsaEncryption),
- mkel(mkbits(pkbytes->data, pkbytes->len),
- nil)));
- freebytes(pkbytes);
- validity = mkseq(
- mkel(mkutc(valid[0]),
- mkel(mkutc(valid[1]),
- nil)));
- certinfo = mkseq(
+ freevalfields(&e.val);
+ e = mkseq(
mkel(mkint(serial),
mkel(mkalg(sigalg),
- mkel(issuer,
- mkel(validity,
- mkel(subject,
- mkel(pubkey,
+ mkel(mkDN(subj),
+ mkel(mkseq(
+ mkel(mkutc(valid[0]),
+ mkel(mkutc(valid[1]),
+ nil))),
+ mkel(mkDN(subj),
+ mkel(mkseq(
+ mkel(mkalg(ALG_rsaEncryption),
+ mkel(mkbits(pkbytes->data, pkbytes->len),
+ nil))),
nil)))))));
- if(encode(certinfo, &certinfobytes) != ASN_OK)
+ freebytes(pkbytes);
+ if(encode(e, &certinfobytes) != ASN_OK)
goto errret;
da = digestalg[sigalg];
(*da->fun)(certinfobytes->data, certinfobytes->len, digest, 0);
freebytes(certinfobytes);
- sig = mkseq(
+ certinfo = e;
+ e = mkseq(
mkel(mkalg(da->alg),
mkel(mkoctet(digest, da->len),
nil)));
- if(encode(sig, &sigbytes) != ASN_OK)
+ if(encode(e, &sigbytes) != ASN_OK){
+ freevalfields(&certinfo.val);
goto errret;
+ }
+ freevalfields(&e.val);
pkcs1 = pkcs1pad(sigbytes, pk->n);
freebytes(sigbytes);
rsadecrypt(priv, pkcs1, pkcs1);
@@ -2585,7 +2584,10 @@
goto errret;
if(certlen)
*certlen = certbytes->len;
- cert = certbytes->data;
+ cert = malloc(certbytes->len);
+ if(cert != nil)
+ memmove(cert, certbytes->data, certbytes->len);
+ freebytes(certbytes);
errret:
freevalfields(&e.val);
return cert;
@@ -2599,39 +2601,39 @@
uchar *cert = nil;
RSApub *pk = rsaprivtopub(priv);
Bytes *certbytes, *pkbytes, *certinfobytes, *sigbytes;
- Elem e, certinfo, subject, pubkey, sig;
+ Elem e, certinfo;
DigestAlg *da;
uchar digest[MAXdlen], *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)
+ e = mkseq(mkel(mkbigint(pk->n),mkel(mkint(mptoi(pk->ek)),nil)));
+ if(encode(e, &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(
+ freevalfields(&e.val);
+ e = mkseq(
mkel(mkint(version),
- mkel(subject,
- mkel(pubkey,
+ mkel(mkDN(subj),
+ mkel(mkseq(
+ mkel(mkalg(ALG_rsaEncryption),
+ mkel(mkbits(pkbytes->data, pkbytes->len),
+ nil))),
nil))));
- if(encode(certinfo, &certinfobytes) != ASN_OK)
+ freebytes(pkbytes);
+ if(encode(e, &certinfobytes) != ASN_OK)
goto errret;
da = digestalg[sigalg];
(*da->fun)(certinfobytes->data, certinfobytes->len, digest, 0);
freebytes(certinfobytes);
- sig = mkseq(
+ certinfo = e;
+ e = mkseq(
mkel(mkalg(da->alg),
mkel(mkoctet(digest, da->len),
nil)));
- if(encode(sig, &sigbytes) != ASN_OK)
+ if(encode(e, &sigbytes) != ASN_OK){
+ freevalfields(&certinfo.val);
goto errret;
+ }
pkcs1 = pkcs1pad(sigbytes, pk->n);
freebytes(sigbytes);
rsadecrypt(priv, pkcs1, pkcs1);
@@ -2647,7 +2649,10 @@
goto errret;
if(certlen)
*certlen = certbytes->len;
- cert = certbytes->data;
+ cert = malloc(certbytes->len);
+ if(cert != nil)
+ memmove(cert, certbytes->data, certbytes->len);
+ freebytes(certbytes);
errret:
freevalfields(&e.val);
return cert;