~mdw
/
sgt
/
putty
/ blobdiff
commit
grep
author
committer
pickaxe
?
search:
re
summary
|
shortlog
|
log
|
commit
|
commitdiff
|
tree
raw
|
inline
| side by side
Centralise calls to fcntl into functions that carefully check the
[sgt/putty]
/
import.c
diff --git
a/import.c
b/import.c
index
55e3be2
..
32a1ac5
100644
(file)
--- a/
import.c
+++ b/
import.c
@@
-289,8
+289,8
@@
static int ssh2_read_mpint(void *data, int len, struct mpint_pos *ret)
if (len < 4)
goto error;
if (len < 4)
goto error;
- bytes =
GET_32BIT(d
);
- if (
len < 4+
bytes)
+ bytes =
toint(GET_32BIT(d)
);
+ if (
bytes < 0 || len-4 <
bytes)
goto error;
ret->start = d + 4;
goto error;
ret->start = d + 4;
@@
-321,7
+321,7
@@
static struct openssh_key *load_openssh_key(const Filename *filename,
const char **errmsg_p)
{
struct openssh_key *ret;
const char **errmsg_p)
{
struct openssh_key *ret;
- FILE *fp;
+ FILE *fp
= NULL
;
char *line = NULL;
char *errmsg, *p;
int headers_done;
char *line = NULL;
char *errmsg, *p;
int headers_done;
@@
-358,7
+358,7
@@
static struct openssh_key *load_openssh_key(const Filename *filename,
errmsg = "unrecognised key type";
goto error;
}
errmsg = "unrecognised key type";
goto error;
}
-
memset(line, 0
, strlen(line));
+
smemclr(line
, strlen(line));
sfree(line);
line = NULL;
sfree(line);
line = NULL;
@@
-370,8
+370,10
@@
static struct openssh_key *load_openssh_key(const Filename *filename,
}
strip_crlf(line);
if (0 == strncmp(line, "-----END ", 9) &&
}
strip_crlf(line);
if (0 == strncmp(line, "-----END ", 9) &&
- 0 == strcmp(line+strlen(line)-16, "PRIVATE KEY-----"))
+ 0 == strcmp(line+strlen(line)-16, "PRIVATE KEY-----")) {
+ sfree(line);
break; /* done */
break; /* done */
+ }
if ((p = strchr(line, ':')) != NULL) {
if (headers_done) {
errmsg = "header found in body of key data";
if ((p = strchr(line, ':')) != NULL) {
if (headers_done) {
errmsg = "header found in body of key data";
@@
-442,17
+444,20
@@
static struct openssh_key *load_openssh_key(const Filename *filename,
memcpy(ret->keyblob + ret->keyblob_len, out, len);
ret->keyblob_len += len;
memcpy(ret->keyblob + ret->keyblob_len, out, len);
ret->keyblob_len += len;
-
memset(out, 0
, sizeof(out));
+
smemclr(out
, sizeof(out));
}
p++;
}
}
}
p++;
}
}
-
memset(line, 0
, strlen(line));
+
smemclr(line
, strlen(line));
sfree(line);
line = NULL;
}
sfree(line);
line = NULL;
}
+ fclose(fp);
+ fp = NULL;
+
if (ret->keyblob_len == 0 || !ret->keyblob) {
errmsg = "key body not present";
goto error;
if (ret->keyblob_len == 0 || !ret->keyblob) {
errmsg = "key body not present";
goto error;
@@
-463,26
+468,27
@@
static struct openssh_key *load_openssh_key(const Filename *filename,
goto error;
}
goto error;
}
-
memset(base64_bit, 0
, sizeof(base64_bit));
+
smemclr(base64_bit
, sizeof(base64_bit));
if (errmsg_p) *errmsg_p = NULL;
return ret;
error:
if (line) {
if (errmsg_p) *errmsg_p = NULL;
return ret;
error:
if (line) {
-
memset(line, 0
, strlen(line));
+
smemclr(line
, strlen(line));
sfree(line);
line = NULL;
}
sfree(line);
line = NULL;
}
-
memset(base64_bit, 0
, sizeof(base64_bit));
+
smemclr(base64_bit
, sizeof(base64_bit));
if (ret) {
if (ret->keyblob) {
if (ret) {
if (ret->keyblob) {
-
memset(ret->keyblob, 0
, ret->keyblob_size);
+
smemclr(ret->keyblob
, ret->keyblob_size);
sfree(ret->keyblob);
}
sfree(ret->keyblob);
}
-
memset(ret, 0
, sizeof(*ret));
+
smemclr(ret
, sizeof(*ret));
sfree(ret);
}
if (errmsg_p) *errmsg_p = errmsg;
sfree(ret);
}
if (errmsg_p) *errmsg_p = errmsg;
+ if (fp) fclose(fp);
return NULL;
}
return NULL;
}
@@
-494,9
+500,9
@@
int openssh_encrypted(const Filename *filename)
if (!key)
return 0;
ret = key->encrypted;
if (!key)
return 0;
ret = key->encrypted;
-
memset(key->keyblob, 0
, key->keyblob_size);
+
smemclr(key->keyblob
, key->keyblob_size);
sfree(key->keyblob);
sfree(key->keyblob);
-
memset(key, 0
, sizeof(*key));
+
smemclr(key
, sizeof(*key));
sfree(key);
return ret;
}
sfree(key);
return ret;
}
@@
-564,8
+570,8
@@
struct ssh2_userkey *openssh_read(const Filename *filename, char *passphrase,
aes_free_context(ctx);
}
aes_free_context(ctx);
}
-
memset(&md5c, 0
, sizeof(md5c));
-
memset(keybuf, 0
, sizeof(keybuf));
+
smemclr(&md5c
, sizeof(md5c));
+
smemclr(keybuf
, sizeof(keybuf));
}
/*
}
/*
@@
-588,12
+594,13
@@
struct ssh2_userkey *openssh_read(const Filename *filename, char *passphrase,
p = key->keyblob;
p = key->keyblob;
- /* Expect the SEQUENCE header. Take its absence as a failure to decrypt. */
+ /* Expect the SEQUENCE header. Take its absence as a failure to
+ * decrypt, if the key was encrypted. */
ret = ber_read_id_len(p, key->keyblob_len, &id, &len, &flags);
p += ret;
if (ret < 0 || id != 16) {
errmsg = "ASN.1 decoding failure";
ret = ber_read_id_len(p, key->keyblob_len, &id, &len, &flags);
p += ret;
if (ret < 0 || id != 16) {
errmsg = "ASN.1 decoding failure";
-
retval = SSH2_WRONG_PASSPHRASE
;
+
retval = key->encrypted ? SSH2_WRONG_PASSPHRASE : NULL
;
goto error;
}
goto error;
}
@@
-625,7
+632,7
@@
struct ssh2_userkey *openssh_read(const Filename *filename, char *passphrase,
if (ret < 0 || id != 2 ||
key->keyblob+key->keyblob_len-p < len) {
errmsg = "ASN.1 decoding failure";
if (ret < 0 || id != 2 ||
key->keyblob+key->keyblob_len-p < len) {
errmsg = "ASN.1 decoding failure";
- retval =
SSH2_WRONG_PASSPHRASE
;
+ retval =
key->encrypted ? SSH2_WRONG_PASSPHRASE : NULL
;
goto error;
}
goto error;
}
@@
-698,12
+705,12
@@
struct ssh2_userkey *openssh_read(const Filename *filename, char *passphrase,
error:
if (blob) {
error:
if (blob) {
-
memset(blob, 0
, blobsize);
+
smemclr(blob
, blobsize);
sfree(blob);
}
sfree(blob);
}
-
memset(key->keyblob, 0
, key->keyblob_size);
+
smemclr(key->keyblob
, key->keyblob_size);
sfree(key->keyblob);
sfree(key->keyblob);
-
memset(key, 0
, sizeof(*key));
+
smemclr(key
, sizeof(*key));
sfree(key);
if (errmsg_p) *errmsg_p = errmsg;
return retval;
sfree(key);
if (errmsg_p) *errmsg_p = errmsg;
return retval;
@@
-740,6
+747,10
@@
int openssh_write(const Filename *filename, struct ssh2_userkey *key,
struct mpint_pos n, e, d, p, q, iqmp, dmp1, dmq1;
Bignum bd, bp, bq, bdmp1, bdmq1;
struct mpint_pos n, e, d, p, q, iqmp, dmp1, dmq1;
Bignum bd, bp, bq, bdmp1, bdmq1;
+ /*
+ * These blobs were generated from inside PuTTY, so we needn't
+ * treat them as untrusted.
+ */
pos = 4 + GET_32BIT(pubblob);
pos += ssh2_read_mpint(pubblob+pos, publen-pos, &e);
pos += ssh2_read_mpint(pubblob+pos, publen-pos, &n);
pos = 4 + GET_32BIT(pubblob);
pos += ssh2_read_mpint(pubblob+pos, publen-pos, &e);
pos += ssh2_read_mpint(pubblob+pos, publen-pos, &n);
@@
-793,6
+804,10
@@
int openssh_write(const Filename *filename, struct ssh2_userkey *key,
int pos;
struct mpint_pos p, q, g, y, x;
int pos;
struct mpint_pos p, q, g, y, x;
+ /*
+ * These blobs were generated from inside PuTTY, so we needn't
+ * treat them as untrusted.
+ */
pos = 4 + GET_32BIT(pubblob);
pos += ssh2_read_mpint(pubblob+pos, publen-pos, &p);
pos += ssh2_read_mpint(pubblob+pos, publen-pos, &q);
pos = 4 + GET_32BIT(pubblob);
pos += ssh2_read_mpint(pubblob+pos, publen-pos, &p);
pos += ssh2_read_mpint(pubblob+pos, publen-pos, &q);
@@
-911,8
+926,8
@@
int openssh_write(const Filename *filename, struct ssh2_userkey *key,
*/
des3_encrypt_pubkey_ossh(keybuf, iv, outblob, outlen);
*/
des3_encrypt_pubkey_ossh(keybuf, iv, outblob, outlen);
-
memset(&md5c, 0
, sizeof(md5c));
-
memset(keybuf, 0
, sizeof(keybuf));
+
smemclr(&md5c
, sizeof(md5c));
+
smemclr(keybuf
, sizeof(keybuf));
}
/*
}
/*
@@
-936,19
+951,19
@@
int openssh_write(const Filename *filename, struct ssh2_userkey *key,
error:
if (outblob) {
error:
if (outblob) {
-
memset(outblob, 0
, outlen);
+
smemclr(outblob
, outlen);
sfree(outblob);
}
if (spareblob) {
sfree(outblob);
}
if (spareblob) {
-
memset(spareblob, 0
, sparelen);
+
smemclr(spareblob
, sparelen);
sfree(spareblob);
}
if (privblob) {
sfree(spareblob);
}
if (privblob) {
-
memset(privblob, 0
, privlen);
+
smemclr(privblob
, privlen);
sfree(privblob);
}
if (pubblob) {
sfree(privblob);
}
if (pubblob) {
-
memset(pubblob, 0
, publen);
+
smemclr(pubblob
, publen);
sfree(pubblob);
}
return ret;
sfree(pubblob);
}
return ret;
@@
-1067,7
+1082,7
@@
static struct sshcom_key *load_sshcom_key(const Filename *filename,
errmsg = "file does not begin with ssh.com key header";
goto error;
}
errmsg = "file does not begin with ssh.com key header";
goto error;
}
-
memset(line, 0
, strlen(line));
+
smemclr(line
, strlen(line));
sfree(line);
line = NULL;
sfree(line);
line = NULL;
@@
-1078,8
+1093,10
@@
static struct sshcom_key *load_sshcom_key(const Filename *filename,
goto error;
}
strip_crlf(line);
goto error;
}
strip_crlf(line);
- if (!strcmp(line, "---- END SSH2 ENCRYPTED PRIVATE KEY ----"))
+ if (!strcmp(line, "---- END SSH2 ENCRYPTED PRIVATE KEY ----")) {
+ sfree(line);
break; /* done */
break; /* done */
+ }
if ((p = strchr(line, ':')) != NULL) {
if (headers_done) {
errmsg = "header found in body of key data";
if ((p = strchr(line, ':')) != NULL) {
if (headers_done) {
errmsg = "header found in body of key data";
@@
-1112,7
+1129,7
@@
static struct sshcom_key *load_sshcom_key(const Filename *filename,
len += line2len - 1;
assert(!line[len]);
len += line2len - 1;
assert(!line[len]);
-
memset(line2, 0
, strlen(line2));
+
smemclr(line2
, strlen(line2));
sfree(line2);
line2 = NULL;
}
sfree(line2);
line2 = NULL;
}
@@
-1158,7
+1175,7
@@
static struct sshcom_key *load_sshcom_key(const Filename *filename,
p++;
}
}
p++;
}
}
-
memset(line, 0
, strlen(line));
+
smemclr(line
, strlen(line));
sfree(line);
line = NULL;
}
sfree(line);
line = NULL;
}
@@
-1168,21
+1185,25
@@
static struct sshcom_key *load_sshcom_key(const Filename *filename,
goto error;
}
goto error;
}
+ fclose(fp);
if (errmsg_p) *errmsg_p = NULL;
return ret;
error:
if (errmsg_p) *errmsg_p = NULL;
return ret;
error:
+ if (fp)
+ fclose(fp);
+
if (line) {
if (line) {
-
memset(line, 0
, strlen(line));
+
smemclr(line
, strlen(line));
sfree(line);
line = NULL;
}
if (ret) {
if (ret->keyblob) {
sfree(line);
line = NULL;
}
if (ret) {
if (ret->keyblob) {
-
memset(ret->keyblob, 0
, ret->keyblob_size);
+
smemclr(ret->keyblob
, ret->keyblob_size);
sfree(ret->keyblob);
}
sfree(ret->keyblob);
}
-
memset(ret, 0
, sizeof(*ret));
+
smemclr(ret
, sizeof(*ret));
sfree(ret);
}
if (errmsg_p) *errmsg_p = errmsg;
sfree(ret);
}
if (errmsg_p) *errmsg_p = errmsg;
@@
-1194,45
+1215,47
@@
int sshcom_encrypted(const Filename *filename, char **comment)
struct sshcom_key *key = load_sshcom_key(filename, NULL);
int pos, len, answer;
struct sshcom_key *key = load_sshcom_key(filename, NULL);
int pos, len, answer;
+ answer = 0;
+
*comment = NULL;
if (!key)
*comment = NULL;
if (!key)
-
return 0
;
+
goto done
;
/*
* Check magic number.
*/
/*
* Check magic number.
*/
- if (GET_32BIT(key->keyblob) != 0x3f6ff9eb)
- return 0; /* key is invalid */
+ if (GET_32BIT(key->keyblob) != 0x3f6ff9eb) {
+ goto done; /* key is invalid */
+ }
/*
* Find the cipher-type string.
*/
/*
* Find the cipher-type string.
*/
- answer = 0;
pos = 8;
if (key->keyblob_len < pos+4)
goto done; /* key is far too short */
pos = 8;
if (key->keyblob_len < pos+4)
goto done; /* key is far too short */
- pos += 4 + GET_32BIT(key->keyblob + pos); /* skip key type */
- if (
key->keyblob_len < pos+
4)
+ len = toint(GET_32BIT(key->keyblob + pos));
+ if (
len < 0 || len > key->keyblob_len - pos -
4)
goto done; /* key is far too short */
goto done; /* key is far too short */
- len = GET_32BIT(key->keyblob + pos); /* find cipher-type length */
- if (key->keyblob_len < pos+4+len)
+ pos += 4 + len; /* skip key type */
+ len = toint(GET_32BIT(key->keyblob + pos)); /* find cipher-type length */
+ if (len < 0 || len > key->keyblob_len - pos - 4)
goto done; /* cipher type string is incomplete */
if (len != 4 || 0 != memcmp(key->keyblob + pos + 4, "none", 4))
answer = 1;
done:
goto done; /* cipher type string is incomplete */
if (len != 4 || 0 != memcmp(key->keyblob + pos + 4, "none", 4))
answer = 1;
done:
- *comment = dupstr(key
->comment
);
-
memset(key->keyblob, 0
, key->keyblob_size);
+ *comment = dupstr(key
? key->comment : ""
);
+
smemclr(key->keyblob
, key->keyblob_size);
sfree(key->keyblob);
sfree(key->keyblob);
-
memset(key, 0
, sizeof(*key));
+
smemclr(key
, sizeof(*key));
sfree(key);
return answer;
}
static int sshcom_read_mpint(void *data, int len, struct mpint_pos *ret)
{
sfree(key);
return answer;
}
static int sshcom_read_mpint(void *data, int len, struct mpint_pos *ret)
{
- int bits;
- int bytes;
+ unsigned bits, bytes;
unsigned char *d = (unsigned char *) data;
if (len < 4)
unsigned char *d = (unsigned char *) data;
if (len < 4)
@@
-1304,7
+1327,8
@@
struct ssh2_userkey *sshcom_read(const Filename *filename, char *passphrase,
*/
pos = 8;
if (key->keyblob_len < pos+4 ||
*/
pos = 8;
if (key->keyblob_len < pos+4 ||
- (len = GET_32BIT(key->keyblob + pos)) > key->keyblob_len - pos - 4) {
+ (len = toint(GET_32BIT(key->keyblob + pos))) < 0 ||
+ len > key->keyblob_len - pos - 4) {
errmsg = "key blob does not contain a key type string";
goto error;
}
errmsg = "key blob does not contain a key type string";
goto error;
}
@@
-1324,7
+1348,8
@@
struct ssh2_userkey *sshcom_read(const Filename *filename, char *passphrase,
* Determine the cipher type.
*/
if (key->keyblob_len < pos+4 ||
* Determine the cipher type.
*/
if (key->keyblob_len < pos+4 ||
- (len = GET_32BIT(key->keyblob + pos)) > key->keyblob_len - pos - 4) {
+ (len = toint(GET_32BIT(key->keyblob + pos))) < 0 ||
+ len > key->keyblob_len - pos - 4) {
errmsg = "key blob does not contain a cipher type string";
goto error;
}
errmsg = "key blob does not contain a cipher type string";
goto error;
}
@@
-1342,7
+1367,8
@@
struct ssh2_userkey *sshcom_read(const Filename *filename, char *passphrase,
* Get hold of the encrypted part of the key.
*/
if (key->keyblob_len < pos+4 ||
* Get hold of the encrypted part of the key.
*/
if (key->keyblob_len < pos+4 ||
- (len = GET_32BIT(key->keyblob + pos)) > key->keyblob_len - pos - 4) {
+ (len = toint(GET_32BIT(key->keyblob + pos))) < 0 ||
+ len > key->keyblob_len - pos - 4) {
errmsg = "key blob does not contain actual key data";
goto error;
}
errmsg = "key blob does not contain actual key data";
goto error;
}
@@
-1390,8
+1416,8
@@
struct ssh2_userkey *sshcom_read(const Filename *filename, char *passphrase,
des3_decrypt_pubkey_ossh(keybuf, iv, (unsigned char *)ciphertext,
cipherlen);
des3_decrypt_pubkey_ossh(keybuf, iv, (unsigned char *)ciphertext,
cipherlen);
-
memset(&md5c, 0
, sizeof(md5c));
-
memset(keybuf, 0
, sizeof(keybuf));
+
smemclr(&md5c
, sizeof(md5c));
+
smemclr(keybuf
, sizeof(keybuf));
/*
* Hereafter we return WRONG_PASSPHRASE for any parsing
/*
* Hereafter we return WRONG_PASSPHRASE for any parsing
@@
-1406,7
+1432,7
@@
struct ssh2_userkey *sshcom_read(const Filename *filename, char *passphrase,
/*
* Strip away the containing string to get to the real meat.
*/
/*
* Strip away the containing string to get to the real meat.
*/
- len =
GET_32BIT(ciphertext
);
+ len =
toint(GET_32BIT(ciphertext)
);
if (len < 0 || len > cipherlen-4) {
errmsg = "containing string was ill-formed";
goto error;
if (len < 0 || len > cipherlen-4) {
errmsg = "containing string was ill-formed";
goto error;
@@
-1447,9
+1473,12
@@
struct ssh2_userkey *sshcom_read(const Filename *filename, char *passphrase,
pos += put_mp(blob+pos, p.start, p.bytes);
pos += put_mp(blob+pos, u.start, u.bytes);
privlen = pos - publen;
pos += put_mp(blob+pos, p.start, p.bytes);
pos += put_mp(blob+pos, u.start, u.bytes);
privlen = pos - publen;
- } else
if (type == DSA)
{
+ } else {
struct mpint_pos p, q, g, x, y;
int pos = 4;
struct mpint_pos p, q, g, x, y;
int pos = 4;
+
+ assert(type == DSA); /* the only other option from the if above */
+
if (GET_32BIT(ciphertext) != 0) {
errmsg = "predefined DSA parameters not supported";
goto error;
if (GET_32BIT(ciphertext) != 0) {
errmsg = "predefined DSA parameters not supported";
goto error;
@@
-1474,8
+1503,7
@@
struct ssh2_userkey *sshcom_read(const Filename *filename, char *passphrase,
publen = pos;
pos += put_mp(blob+pos, x.start, x.bytes);
privlen = pos - publen;
publen = pos;
pos += put_mp(blob+pos, x.start, x.bytes);
privlen = pos - publen;
- } else
- return NULL;
+ }
assert(privlen > 0); /* should have bombed by now if not */
assert(privlen > 0); /* should have bombed by now if not */
@@
-1494,12
+1522,12
@@
struct ssh2_userkey *sshcom_read(const Filename *filename, char *passphrase,
error:
if (blob) {
error:
if (blob) {
-
memset(blob, 0
, blobsize);
+
smemclr(blob
, blobsize);
sfree(blob);
}
sfree(blob);
}
-
memset(key->keyblob, 0
, key->keyblob_size);
+
smemclr(key->keyblob
, key->keyblob_size);
sfree(key->keyblob);
sfree(key->keyblob);
-
memset(key, 0
, sizeof(*key));
+
smemclr(key
, sizeof(*key));
sfree(key);
if (errmsg_p) *errmsg_p = errmsg;
return ret;
sfree(key);
if (errmsg_p) *errmsg_p = errmsg;
return ret;
@@
-1535,6
+1563,10
@@
int sshcom_write(const Filename *filename, struct ssh2_userkey *key,
int pos;
struct mpint_pos n, e, d, p, q, iqmp;
int pos;
struct mpint_pos n, e, d, p, q, iqmp;
+ /*
+ * These blobs were generated from inside PuTTY, so we needn't
+ * treat them as untrusted.
+ */
pos = 4 + GET_32BIT(pubblob);
pos += ssh2_read_mpint(pubblob+pos, publen-pos, &e);
pos += ssh2_read_mpint(pubblob+pos, publen-pos, &n);
pos = 4 + GET_32BIT(pubblob);
pos += ssh2_read_mpint(pubblob+pos, publen-pos, &e);
pos += ssh2_read_mpint(pubblob+pos, publen-pos, &n);
@@
-1560,6
+1592,10
@@
int sshcom_write(const Filename *filename, struct ssh2_userkey *key,
int pos;
struct mpint_pos p, q, g, y, x;
int pos;
struct mpint_pos p, q, g, y, x;
+ /*
+ * These blobs were generated from inside PuTTY, so we needn't
+ * treat them as untrusted.
+ */
pos = 4 + GET_32BIT(pubblob);
pos += ssh2_read_mpint(pubblob+pos, publen-pos, &p);
pos += ssh2_read_mpint(pubblob+pos, publen-pos, &q);
pos = 4 + GET_32BIT(pubblob);
pos += ssh2_read_mpint(pubblob+pos, publen-pos, &p);
pos += ssh2_read_mpint(pubblob+pos, publen-pos, &q);
@@
-1664,8
+1700,8
@@
int sshcom_write(const Filename *filename, struct ssh2_userkey *key,
des3_encrypt_pubkey_ossh(keybuf, iv, (unsigned char *)ciphertext,
cipherlen);
des3_encrypt_pubkey_ossh(keybuf, iv, (unsigned char *)ciphertext,
cipherlen);
-
memset(&md5c, 0
, sizeof(md5c));
-
memset(keybuf, 0
, sizeof(keybuf));
+
smemclr(&md5c
, sizeof(md5c));
+
smemclr(keybuf
, sizeof(keybuf));
}
/*
}
/*
@@
-1700,15
+1736,15
@@
int sshcom_write(const Filename *filename, struct ssh2_userkey *key,
error:
if (outblob) {
error:
if (outblob) {
-
memset(outblob, 0
, outlen);
+
smemclr(outblob
, outlen);
sfree(outblob);
}
if (privblob) {
sfree(outblob);
}
if (privblob) {
-
memset(privblob, 0
, privlen);
+
smemclr(privblob
, privlen);
sfree(privblob);
}
if (pubblob) {
sfree(privblob);
}
if (pubblob) {
-
memset(pubblob, 0
, publen);
+
smemclr(pubblob
, publen);
sfree(pubblob);
}
return ret;
sfree(pubblob);
}
return ret;