mirror of
https://git.tartarus.org/simon/putty.git
synced 2025-01-09 17:38:00 +00:00
Improve the base64 utility functions.
The low-level functions to handle a single atom of base64 at a time have been in 'utils' / misc.h for ages, but the higher-level family of base64_encode functions that handle a whole data block were hidden away in sshpubk.c, and there was no higher-level decode function at all. Now moved both into 'utils' modules and declared them in misc.h rather than ssh.h. Also, improved the APIs: they all take ptrlen in place of separate data and length arguments, their naming is more consistent and more explicit (the previous base64_encode which didn't name its destination is now base64_encode_fp), and the encode functions now accept cpl == 0 as a special case meaning that the output base64 data is wanted in the form of an unbroken single-line string with no trailing \n.
This commit is contained in:
parent
1bd2af1f87
commit
043c24844a
6
import.c
6
import.c
@ -1075,7 +1075,7 @@ static bool openssh_pem_write(
|
|||||||
fprintf(fp, "%02X", iv[i]);
|
fprintf(fp, "%02X", iv[i]);
|
||||||
fprintf(fp, "\n\n");
|
fprintf(fp, "\n\n");
|
||||||
}
|
}
|
||||||
base64_encode(fp, outblob->u, outblob->len, 64);
|
base64_encode_fp(fp, ptrlen_from_strbuf(outblob), 64);
|
||||||
fputs(footer, fp);
|
fputs(footer, fp);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
ret = true;
|
ret = true;
|
||||||
@ -1606,7 +1606,7 @@ static bool openssh_new_write(
|
|||||||
if (!fp)
|
if (!fp)
|
||||||
goto error;
|
goto error;
|
||||||
fputs("-----BEGIN OPENSSH PRIVATE KEY-----\n", fp);
|
fputs("-----BEGIN OPENSSH PRIVATE KEY-----\n", fp);
|
||||||
base64_encode(fp, cblob->u, cblob->len, 64);
|
base64_encode_fp(fp, ptrlen_from_strbuf(cblob), 64);
|
||||||
fputs("-----END OPENSSH PRIVATE KEY-----\n", fp);
|
fputs("-----END OPENSSH PRIVATE KEY-----\n", fp);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
ret = true;
|
ret = true;
|
||||||
@ -2308,7 +2308,7 @@ static bool sshcom_write(
|
|||||||
}
|
}
|
||||||
fprintf(fp, "%s\"\n", c);
|
fprintf(fp, "%s\"\n", c);
|
||||||
}
|
}
|
||||||
base64_encode(fp, outblob->u, outblob->len, 70);
|
base64_encode_fp(fp, ptrlen_from_strbuf(outblob), 70);
|
||||||
fputs("---- END SSH2 ENCRYPTED PRIVATE KEY ----\n", fp);
|
fputs("---- END SSH2 ENCRYPTED PRIVATE KEY ----\n", fp);
|
||||||
fclose(fp);
|
fclose(fp);
|
||||||
ret = true;
|
ret = true;
|
||||||
|
6
misc.h
6
misc.h
@ -108,6 +108,12 @@ bool strendswith(const char *s, const char *t);
|
|||||||
|
|
||||||
void base64_encode_atom(const unsigned char *data, int n, char *out);
|
void base64_encode_atom(const unsigned char *data, int n, char *out);
|
||||||
int base64_decode_atom(const char *atom, unsigned char *out);
|
int base64_decode_atom(const char *atom, unsigned char *out);
|
||||||
|
void base64_decode_bs(BinarySink *bs, ptrlen data);
|
||||||
|
void base64_decode_fp(FILE *fp, ptrlen data);
|
||||||
|
strbuf *base64_decode_sb(ptrlen data);
|
||||||
|
void base64_encode_bs(BinarySink *bs, ptrlen data, int cpl);
|
||||||
|
void base64_encode_fp(FILE *fp, ptrlen data, int cpl);
|
||||||
|
strbuf *base64_encode_sb(ptrlen data, int cpl);
|
||||||
|
|
||||||
struct bufchain_granule;
|
struct bufchain_granule;
|
||||||
struct bufchain_tag {
|
struct bufchain_tag {
|
||||||
|
4
ssh.h
4
ssh.h
@ -1290,11 +1290,7 @@ static inline bool is_base64_char(char c)
|
|||||||
c == '+' || c == '/' || c == '=');
|
c == '+' || c == '/' || c == '=');
|
||||||
}
|
}
|
||||||
|
|
||||||
extern int base64_decode_atom(const char *atom, unsigned char *out);
|
|
||||||
extern int base64_lines(int datalen);
|
extern int base64_lines(int datalen);
|
||||||
extern void base64_encode_atom(const unsigned char *data, int n, char *out);
|
|
||||||
extern void base64_encode(FILE *fp, const unsigned char *data, int datalen,
|
|
||||||
int cpl);
|
|
||||||
|
|
||||||
/* ppk_load_* can return this as an error */
|
/* ppk_load_* can return this as an error */
|
||||||
extern ssh2_userkey ssh2_wrong_passphrase;
|
extern ssh2_userkey ssh2_wrong_passphrase;
|
||||||
|
37
sshpubk.c
37
sshpubk.c
@ -1391,37 +1391,6 @@ int base64_lines(int datalen)
|
|||||||
return (datalen + 47) / 48;
|
return (datalen + 47) / 48;
|
||||||
}
|
}
|
||||||
|
|
||||||
static void base64_encode_s(BinarySink *bs, const unsigned char *data,
|
|
||||||
int datalen, int cpl)
|
|
||||||
{
|
|
||||||
int linelen = 0;
|
|
||||||
char out[4];
|
|
||||||
int n, i;
|
|
||||||
|
|
||||||
while (datalen > 0) {
|
|
||||||
n = (datalen < 3 ? datalen : 3);
|
|
||||||
base64_encode_atom(data, n, out);
|
|
||||||
data += n;
|
|
||||||
datalen -= n;
|
|
||||||
for (i = 0; i < 4; i++) {
|
|
||||||
if (linelen >= cpl) {
|
|
||||||
linelen = 0;
|
|
||||||
put_byte(bs, '\n');
|
|
||||||
}
|
|
||||||
put_byte(bs, out[i]);
|
|
||||||
linelen++;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
put_byte(bs, '\n');
|
|
||||||
}
|
|
||||||
|
|
||||||
void base64_encode(FILE *fp, const unsigned char *data, int datalen, int cpl)
|
|
||||||
{
|
|
||||||
stdio_sink ss;
|
|
||||||
stdio_sink_init(&ss, fp);
|
|
||||||
base64_encode_s(BinarySink_UPCAST(&ss), data, datalen, cpl);
|
|
||||||
}
|
|
||||||
|
|
||||||
const ppk_save_parameters ppk_save_default_parameters = {
|
const ppk_save_parameters ppk_save_default_parameters = {
|
||||||
.fmt_version = 3,
|
.fmt_version = 3,
|
||||||
|
|
||||||
@ -1566,7 +1535,7 @@ strbuf *ppk_save_sb(ssh2_userkey *key, const char *passphrase,
|
|||||||
put_fmt(out, "Encryption: %s\n", cipherstr);
|
put_fmt(out, "Encryption: %s\n", cipherstr);
|
||||||
put_fmt(out, "Comment: %s\n", key->comment);
|
put_fmt(out, "Comment: %s\n", key->comment);
|
||||||
put_fmt(out, "Public-Lines: %d\n", base64_lines(pub_blob->len));
|
put_fmt(out, "Public-Lines: %d\n", base64_lines(pub_blob->len));
|
||||||
base64_encode_s(BinarySink_UPCAST(out), pub_blob->u, pub_blob->len, 64);
|
base64_encode_bs(BinarySink_UPCAST(out), ptrlen_from_strbuf(pub_blob), 64);
|
||||||
if (params.fmt_version == 3 && ciphertype->keylen != 0) {
|
if (params.fmt_version == 3 && ciphertype->keylen != 0) {
|
||||||
put_fmt(out, "Key-Derivation: %s\n",
|
put_fmt(out, "Key-Derivation: %s\n",
|
||||||
params.argon2_flavour == Argon2d ? "Argon2d" :
|
params.argon2_flavour == Argon2d ? "Argon2d" :
|
||||||
@ -1582,8 +1551,8 @@ strbuf *ppk_save_sb(ssh2_userkey *key, const char *passphrase,
|
|||||||
put_fmt(out, "\n");
|
put_fmt(out, "\n");
|
||||||
}
|
}
|
||||||
put_fmt(out, "Private-Lines: %d\n", base64_lines(priv_encrypted_len));
|
put_fmt(out, "Private-Lines: %d\n", base64_lines(priv_encrypted_len));
|
||||||
base64_encode_s(BinarySink_UPCAST(out),
|
base64_encode_bs(BinarySink_UPCAST(out),
|
||||||
priv_blob_encrypted, priv_encrypted_len, 64);
|
make_ptrlen(priv_blob_encrypted, priv_encrypted_len), 64);
|
||||||
put_fmt(out, "Private-MAC: ");
|
put_fmt(out, "Private-MAC: ");
|
||||||
for (i = 0; i < macalg->len; i++)
|
for (i = 0; i < macalg->len; i++)
|
||||||
put_fmt(out, "%02x", priv_mac[i]);
|
put_fmt(out, "%02x", priv_mac[i]);
|
||||||
|
@ -2,7 +2,9 @@ add_sources_from_current_dir(utils
|
|||||||
antispoof.c
|
antispoof.c
|
||||||
backend_socket_log.c
|
backend_socket_log.c
|
||||||
base64_decode_atom.c
|
base64_decode_atom.c
|
||||||
|
base64_decode.c
|
||||||
base64_encode_atom.c
|
base64_encode_atom.c
|
||||||
|
base64_encode.c
|
||||||
bufchain.c
|
bufchain.c
|
||||||
buildinfo.c
|
buildinfo.c
|
||||||
burnstr.c
|
burnstr.c
|
||||||
|
37
utils/base64_decode.c
Normal file
37
utils/base64_decode.c
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
#include "misc.h"
|
||||||
|
|
||||||
|
void base64_decode_bs(BinarySink *bs, ptrlen input)
|
||||||
|
{
|
||||||
|
BinarySource src[1];
|
||||||
|
BinarySource_BARE_INIT_PL(src, input);
|
||||||
|
|
||||||
|
while (get_avail(src)) {
|
||||||
|
char b64atom[4];
|
||||||
|
unsigned char binatom[3];
|
||||||
|
|
||||||
|
for (size_t i = 0; i < 4 ;) {
|
||||||
|
char c = get_byte(src);
|
||||||
|
if (get_err(src))
|
||||||
|
c = '=';
|
||||||
|
if (c == '\n' || c == '\r')
|
||||||
|
continue;
|
||||||
|
b64atom[i++] = c;
|
||||||
|
}
|
||||||
|
|
||||||
|
put_data(bs, binatom, base64_decode_atom(b64atom, binatom));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void base64_decode_fp(FILE *fp, ptrlen input)
|
||||||
|
{
|
||||||
|
stdio_sink ss;
|
||||||
|
stdio_sink_init(&ss, fp);
|
||||||
|
base64_decode_bs(BinarySink_UPCAST(&ss), input);
|
||||||
|
}
|
||||||
|
|
||||||
|
strbuf *base64_decode_sb(ptrlen input)
|
||||||
|
{
|
||||||
|
strbuf *sb = strbuf_new_nm();
|
||||||
|
base64_decode_bs(BinarySink_UPCAST(sb), input);
|
||||||
|
return sb;
|
||||||
|
}
|
40
utils/base64_encode.c
Normal file
40
utils/base64_encode.c
Normal file
@ -0,0 +1,40 @@
|
|||||||
|
#include "misc.h"
|
||||||
|
|
||||||
|
void base64_encode_bs(BinarySink *bs, ptrlen input, int cpl)
|
||||||
|
{
|
||||||
|
BinarySource src[1];
|
||||||
|
BinarySource_BARE_INIT_PL(src, input);
|
||||||
|
int linelen = 0;
|
||||||
|
|
||||||
|
while (get_avail(src)) {
|
||||||
|
size_t n = get_avail(src) < 3 ? get_avail(src) : 3;
|
||||||
|
ptrlen binatom = get_data(src, n);
|
||||||
|
|
||||||
|
char b64atom[4];
|
||||||
|
base64_encode_atom(binatom.ptr, binatom.len, b64atom);
|
||||||
|
for (size_t i = 0; i < 4; i++) {
|
||||||
|
if (cpl > 0 && linelen >= cpl) {
|
||||||
|
linelen = 0;
|
||||||
|
put_byte(bs, '\n');
|
||||||
|
}
|
||||||
|
put_byte(bs, b64atom[i]);
|
||||||
|
linelen++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (cpl > 0)
|
||||||
|
put_byte(bs, '\n');
|
||||||
|
}
|
||||||
|
|
||||||
|
void base64_encode_fp(FILE *fp, ptrlen input, int cpl)
|
||||||
|
{
|
||||||
|
stdio_sink ss;
|
||||||
|
stdio_sink_init(&ss, fp);
|
||||||
|
base64_encode_bs(BinarySink_UPCAST(&ss), input, cpl);
|
||||||
|
}
|
||||||
|
|
||||||
|
strbuf *base64_encode_sb(ptrlen input, int cpl)
|
||||||
|
{
|
||||||
|
strbuf *sb = strbuf_new_nm();
|
||||||
|
base64_encode_bs(BinarySink_UPCAST(sb), input, cpl);
|
||||||
|
return sb;
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user