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.
This commit is contained in:
parent
5639f9504b
commit
6641548938
1 changed files with 48 additions and 43 deletions
|
@ -2529,47 +2529,46 @@ X509gen(RSApriv *priv, char *subj, ulong valid[2], int *certlen)
|
||||||
uchar *cert = nil;
|
uchar *cert = nil;
|
||||||
RSApub *pk = rsaprivtopub(priv);
|
RSApub *pk = rsaprivtopub(priv);
|
||||||
Bytes *certbytes, *pkbytes, *certinfobytes, *sigbytes;
|
Bytes *certbytes, *pkbytes, *certinfobytes, *sigbytes;
|
||||||
Elem e, certinfo, issuer, subject, pubkey, validity, sig;
|
Elem e, certinfo;
|
||||||
DigestAlg *da;
|
DigestAlg *da;
|
||||||
uchar digest[MAXdlen], *buf;
|
uchar digest[MAXdlen], *buf;
|
||||||
int buflen;
|
int buflen;
|
||||||
mpint *pkcs1;
|
mpint *pkcs1;
|
||||||
|
|
||||||
e.val.tag = VInt; /* so freevalfields at errret is no-op */
|
e = mkseq(mkel(mkbigint(pk->n),mkel(mkint(mptoi(pk->ek)),nil)));
|
||||||
issuer = mkDN(subj);
|
if(encode(e, &pkbytes) != ASN_OK)
|
||||||
subject = mkDN(subj);
|
|
||||||
pubkey = mkseq(mkel(mkbigint(pk->n),mkel(mkint(mptoi(pk->ek)),nil)));
|
|
||||||
if(encode(pubkey, &pkbytes) != ASN_OK)
|
|
||||||
goto errret;
|
goto errret;
|
||||||
freevalfields(&pubkey.val);
|
freevalfields(&e.val);
|
||||||
pubkey = mkseq(
|
e = 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(
|
|
||||||
mkel(mkint(serial),
|
mkel(mkint(serial),
|
||||||
mkel(mkalg(sigalg),
|
mkel(mkalg(sigalg),
|
||||||
mkel(issuer,
|
mkel(mkDN(subj),
|
||||||
mkel(validity,
|
mkel(mkseq(
|
||||||
mkel(subject,
|
mkel(mkutc(valid[0]),
|
||||||
mkel(pubkey,
|
mkel(mkutc(valid[1]),
|
||||||
|
nil))),
|
||||||
|
mkel(mkDN(subj),
|
||||||
|
mkel(mkseq(
|
||||||
|
mkel(mkalg(ALG_rsaEncryption),
|
||||||
|
mkel(mkbits(pkbytes->data, pkbytes->len),
|
||||||
|
nil))),
|
||||||
nil)))))));
|
nil)))))));
|
||||||
if(encode(certinfo, &certinfobytes) != ASN_OK)
|
freebytes(pkbytes);
|
||||||
|
if(encode(e, &certinfobytes) != ASN_OK)
|
||||||
goto errret;
|
goto errret;
|
||||||
da = digestalg[sigalg];
|
da = digestalg[sigalg];
|
||||||
(*da->fun)(certinfobytes->data, certinfobytes->len, digest, 0);
|
(*da->fun)(certinfobytes->data, certinfobytes->len, digest, 0);
|
||||||
freebytes(certinfobytes);
|
freebytes(certinfobytes);
|
||||||
sig = mkseq(
|
certinfo = e;
|
||||||
|
e = mkseq(
|
||||||
mkel(mkalg(da->alg),
|
mkel(mkalg(da->alg),
|
||||||
mkel(mkoctet(digest, da->len),
|
mkel(mkoctet(digest, da->len),
|
||||||
nil)));
|
nil)));
|
||||||
if(encode(sig, &sigbytes) != ASN_OK)
|
if(encode(e, &sigbytes) != ASN_OK){
|
||||||
|
freevalfields(&certinfo.val);
|
||||||
goto errret;
|
goto errret;
|
||||||
|
}
|
||||||
|
freevalfields(&e.val);
|
||||||
pkcs1 = pkcs1pad(sigbytes, pk->n);
|
pkcs1 = pkcs1pad(sigbytes, pk->n);
|
||||||
freebytes(sigbytes);
|
freebytes(sigbytes);
|
||||||
rsadecrypt(priv, pkcs1, pkcs1);
|
rsadecrypt(priv, pkcs1, pkcs1);
|
||||||
|
@ -2585,7 +2584,10 @@ X509gen(RSApriv *priv, char *subj, ulong valid[2], int *certlen)
|
||||||
goto errret;
|
goto errret;
|
||||||
if(certlen)
|
if(certlen)
|
||||||
*certlen = certbytes->len;
|
*certlen = certbytes->len;
|
||||||
cert = certbytes->data;
|
cert = malloc(certbytes->len);
|
||||||
|
if(cert != nil)
|
||||||
|
memmove(cert, certbytes->data, certbytes->len);
|
||||||
|
freebytes(certbytes);
|
||||||
errret:
|
errret:
|
||||||
freevalfields(&e.val);
|
freevalfields(&e.val);
|
||||||
return cert;
|
return cert;
|
||||||
|
@ -2599,39 +2601,39 @@ X509req(RSApriv *priv, char *subj, int *certlen)
|
||||||
uchar *cert = nil;
|
uchar *cert = nil;
|
||||||
RSApub *pk = rsaprivtopub(priv);
|
RSApub *pk = rsaprivtopub(priv);
|
||||||
Bytes *certbytes, *pkbytes, *certinfobytes, *sigbytes;
|
Bytes *certbytes, *pkbytes, *certinfobytes, *sigbytes;
|
||||||
Elem e, certinfo, subject, pubkey, sig;
|
Elem e, certinfo;
|
||||||
DigestAlg *da;
|
DigestAlg *da;
|
||||||
uchar digest[MAXdlen], *buf;
|
uchar digest[MAXdlen], *buf;
|
||||||
int buflen;
|
int buflen;
|
||||||
mpint *pkcs1;
|
mpint *pkcs1;
|
||||||
|
|
||||||
e.val.tag = VInt; /* so freevalfields at errret is no-op */
|
e = mkseq(mkel(mkbigint(pk->n),mkel(mkint(mptoi(pk->ek)),nil)));
|
||||||
subject = mkDN(subj);
|
if(encode(e, &pkbytes) != ASN_OK)
|
||||||
pubkey = mkseq(mkel(mkbigint(pk->n),mkel(mkint(mptoi(pk->ek)),nil)));
|
|
||||||
if(encode(pubkey, &pkbytes) != ASN_OK)
|
|
||||||
goto errret;
|
goto errret;
|
||||||
freevalfields(&pubkey.val);
|
freevalfields(&e.val);
|
||||||
pubkey = mkseq(
|
e = mkseq(
|
||||||
mkel(mkalg(ALG_rsaEncryption),
|
|
||||||
mkel(mkbits(pkbytes->data, pkbytes->len),
|
|
||||||
nil)));
|
|
||||||
freebytes(pkbytes);
|
|
||||||
certinfo = mkseq(
|
|
||||||
mkel(mkint(version),
|
mkel(mkint(version),
|
||||||
mkel(subject,
|
mkel(mkDN(subj),
|
||||||
mkel(pubkey,
|
mkel(mkseq(
|
||||||
|
mkel(mkalg(ALG_rsaEncryption),
|
||||||
|
mkel(mkbits(pkbytes->data, pkbytes->len),
|
||||||
|
nil))),
|
||||||
nil))));
|
nil))));
|
||||||
if(encode(certinfo, &certinfobytes) != ASN_OK)
|
freebytes(pkbytes);
|
||||||
|
if(encode(e, &certinfobytes) != ASN_OK)
|
||||||
goto errret;
|
goto errret;
|
||||||
da = digestalg[sigalg];
|
da = digestalg[sigalg];
|
||||||
(*da->fun)(certinfobytes->data, certinfobytes->len, digest, 0);
|
(*da->fun)(certinfobytes->data, certinfobytes->len, digest, 0);
|
||||||
freebytes(certinfobytes);
|
freebytes(certinfobytes);
|
||||||
sig = mkseq(
|
certinfo = e;
|
||||||
|
e = mkseq(
|
||||||
mkel(mkalg(da->alg),
|
mkel(mkalg(da->alg),
|
||||||
mkel(mkoctet(digest, da->len),
|
mkel(mkoctet(digest, da->len),
|
||||||
nil)));
|
nil)));
|
||||||
if(encode(sig, &sigbytes) != ASN_OK)
|
if(encode(e, &sigbytes) != ASN_OK){
|
||||||
|
freevalfields(&certinfo.val);
|
||||||
goto errret;
|
goto errret;
|
||||||
|
}
|
||||||
pkcs1 = pkcs1pad(sigbytes, pk->n);
|
pkcs1 = pkcs1pad(sigbytes, pk->n);
|
||||||
freebytes(sigbytes);
|
freebytes(sigbytes);
|
||||||
rsadecrypt(priv, pkcs1, pkcs1);
|
rsadecrypt(priv, pkcs1, pkcs1);
|
||||||
|
@ -2647,7 +2649,10 @@ X509req(RSApriv *priv, char *subj, int *certlen)
|
||||||
goto errret;
|
goto errret;
|
||||||
if(certlen)
|
if(certlen)
|
||||||
*certlen = certbytes->len;
|
*certlen = certbytes->len;
|
||||||
cert = certbytes->data;
|
cert = malloc(certbytes->len);
|
||||||
|
if(cert != nil)
|
||||||
|
memmove(cert, certbytes->data, certbytes->len);
|
||||||
|
freebytes(certbytes);
|
||||||
errret:
|
errret:
|
||||||
freevalfields(&e.val);
|
freevalfields(&e.val);
|
||||||
return cert;
|
return cert;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue