static GBytes * base64_encode (GBytes *bytes) { gconstpointer data; gchar *encoded; gsize length; gint state = 0; gint save = 0; data = g_bytes_get_data (bytes, &length); if (length == 0) return g_bytes_new_static ("", 0); /* We can use a smaller limit here, since we know the saved state is 0, +1 is needed for trailing \0, also check for unlikely integer overflow */ if (length >= ((G_MAXSIZE - 1) / 4 - 1) * 3) g_error ("%s: input too large for Base64 encoding (%"G_GSIZE_FORMAT" chars)", G_STRLOC, length); encoded = g_malloc ((length / 3 + 1) * 4 + 4); length = g_base64_encode_step (data, length, FALSE, encoded, &state, &save); length += g_base64_encode_close (FALSE, encoded + length, &state, &save); return g_bytes_new_take (encoded, length); }
/* according to rfc2849, value_spec must be either 7-bit ASCII (safe-string) or a base64-string. Or an url, which is not implemented yet. */ static gchar* string_to_value_spec(const gchar* str) { gboolean issafe = TRUE; const gchar* p; for(p = str; *p != '\0' && issafe; p++) issafe = (*p &0x80) == 0; if (issafe) { return g_strconcat(" ",str, NULL); } else { gsize len; gsize sz; gchar *res; gsize outlen; gint state = 0; gint save = 0; len = strlen(str); sz = (len / 3 + 1) * 4 + 1; res = g_malloc(sz + 2); strcpy(res, ": "); outlen = g_base64_encode_step((const guchar *) str, len, FALSE, res + 2, &state, &save); outlen += g_base64_encode_close(FALSE, res + 2 + outlen, &state, &save); res[2 + outlen] = '\0'; return res; } }
static void insert_crypto(struct call_media *media, struct sdp_chopper *chop) { char b64_buf[((SRTP_MAX_MASTER_KEY_LEN + SRTP_MAX_MASTER_SALT_LEN) / 3 + 1) * 4 + 4]; char *p; int state = 0, save = 0, i; struct crypto_params *cp = &media->sdes_out.params; unsigned long long ull; if (!cp->crypto_suite || !MEDIA_ISSET(media, SDES) || MEDIA_ISSET(media, PASSTHRU)) return; p = b64_buf; p += g_base64_encode_step((unsigned char *) cp->master_key, cp->crypto_suite->master_key_len, 0, p, &state, &save); p += g_base64_encode_step((unsigned char *) cp->master_salt, cp->crypto_suite->master_salt_len, 0, p, &state, &save); p += g_base64_encode_close(0, p, &state, &save); chopper_append_c(chop, "a=crypto:"); chopper_append_printf(chop, "%u ", media->sdes_out.tag); chopper_append_c(chop, cp->crypto_suite->name); chopper_append_c(chop, " inline:"); chopper_append_dup(chop, b64_buf, p - b64_buf); if (cp->mki_len) { ull = 0; for (i = 0; i < cp->mki_len && i < sizeof(ull); i++) ull |= cp->mki[cp->mki_len - i - 1] << (i * 8); chopper_append_printf(chop, "|%llu:%u", ull, cp->mki_len); } if (cp->session_params.unencrypted_srtp) chopper_append_c(chop, " UNENCRYPTED_SRTP"); if (cp->session_params.unencrypted_srtcp) chopper_append_c(chop, " UNENCRYPTED_SRTCP"); if (cp->session_params.unauthenticated_srtp) chopper_append_c(chop, " UNAUTHENTICATED_SRTP"); chopper_append_c(chop, "\r\n"); }
static gchar* _make_rsasha1_base64_signature(const gchar* base_string, const gchar* key) { gnutls_privkey_t pkey; gnutls_x509_privkey_t x509_pkey; gnutls_datum_t pkey_data; gnutls_datum_t signature; gchar* out = NULL; pkey_data.data = (guchar*)key; pkey_data.size = strlen(key); gnutls_privkey_init(&pkey); gnutls_x509_privkey_init(&x509_pkey); int res = gnutls_x509_privkey_import(x509_pkey, &pkey_data, GNUTLS_X509_FMT_PEM); if (res != GNUTLS_E_SUCCESS) { goto out; } res = gnutls_privkey_import_x509(pkey, x509_pkey, 0); if (res != GNUTLS_E_SUCCESS) { goto out; } res = gnutls_privkey_sign_data(pkey, GNUTLS_DIG_SHA1, 0, &pkey_data, &signature); if (res != GNUTLS_E_SUCCESS) { goto out; } out = g_malloc0((signature.size / 3 + 1) * 4 + 4); gint state = 0; gint save = 0; gchar* p = out; p += g_base64_encode_step(signature.data, signature.size, FALSE, p, &state, &save); g_base64_encode_close(FALSE, p, &state, &save); gnutls_free(signature.data); out: gnutls_x509_privkey_deinit(x509_pkey); gnutls_privkey_deinit(pkey); return out; }
guchar* egg_openssl_pem_write (const guchar *data, gsize n_data, GQuark type, GHashTable *headers, gsize *n_result) { GString *string; gint state, save; gsize length, n_prefix; g_return_val_if_fail (data || !n_data, NULL); g_return_val_if_fail (type, NULL); g_return_val_if_fail (n_result, NULL); string = g_string_sized_new (4096); /* The prefix */ g_string_append_len (string, PEM_PREF_BEGIN, PEM_PREF_BEGIN_L); g_string_append (string, g_quark_to_string (type)); g_string_append_len (string, PEM_SUFF, PEM_SUFF_L); g_string_append_c (string, '\n'); /* The headers */ if (headers && g_hash_table_size (headers) > 0) { g_hash_table_foreach (headers, append_each_header, string); g_string_append_c (string, '\n'); } /* Resize string to fit the base64 data. Algorithm from Glib reference */ length = n_data * 4 / 3 + n_data * 4 / (3 * 72) + 7; n_prefix = string->len; g_string_set_size (string, n_prefix + length); /* The actual base64 data */ state = save = 0; length = g_base64_encode_step (data, n_data, TRUE, string->str + string->len, &state, &save); g_string_set_size (string, n_prefix + length); /* The suffix */ g_string_append_c (string, '\n'); g_string_append_len (string, PEM_PREF_END, PEM_PREF_END_L); g_string_append (string, g_quark_to_string (type)); g_string_append_len (string, PEM_SUFF, PEM_SUFF_L); g_string_append_c (string, '\n'); *n_result = string->len; return (guchar*)g_string_free (string, FALSE); }
static gboolean _pixbuf_encode (const gchar *buf, gsize count, GError **error, gpointer data) { EncodeData *ed = data; gsize growth = (count / 3 + 1) * 4 + 4 + ((count / 3 + 1) * 4 + 4) / 72 + 1; gchar *out; g_byte_array_set_size (ed->array, ed->size + growth); out = (gchar *)&ed->array->data[ed->size]; ed->size += g_base64_encode_step ((guchar *)buf, count, TRUE, out, &ed->state, &ed->save); return TRUE; }
void sp_embed_image(Inkscape::XML::Node *image_node, Inkscape::Pixbuf *pb) { bool free_data = false; // check whether the pixbuf has MIME data guchar *data = NULL; gsize len = 0; std::string data_mimetype; data = const_cast<guchar *>(pb->getMimeData(len, data_mimetype)); if (data == NULL) { // if there is no supported MIME data, embed as PNG data_mimetype = "image/png"; gdk_pixbuf_save_to_buffer(pb->getPixbufRaw(), reinterpret_cast<gchar**>(&data), &len, "png", NULL, NULL); free_data = true; } // Save base64 encoded data in image node // this formula taken from Glib docs gsize needed_size = len * 4 / 3 + len * 4 / (3 * 72) + 7; needed_size += 5 + 8 + data_mimetype.size(); // 5 bytes for data: + 8 for ;base64, gchar *buffer = (gchar *) g_malloc(needed_size); gchar *buf_work = buffer; buf_work += g_sprintf(buffer, "data:%s;base64,", data_mimetype.c_str()); gint state = 0; gint save = 0; gsize written = 0; written += g_base64_encode_step(data, len, TRUE, buf_work, &state, &save); written += g_base64_encode_close(TRUE, buf_work + written, &state, &save); buf_work[written] = 0; // null terminate // TODO: this is very wasteful memory-wise. // It would be better to only keep the binary data around, // and base64 encode on the fly when saving the XML. image_node->setAttribute("xlink:href", buffer); g_free(buffer); if (free_data) g_free(data); }
static void multipart_set_boundary (CamelMultipart *multipart, const gchar *boundary) { CamelDataWrapper *cdw = CAMEL_DATA_WRAPPER (multipart); gchar *bgen, bbuf[27], *p; guint8 *digest; gsize length; gint state, save; g_return_if_fail (cdw->mime_type != NULL); length = g_checksum_type_get_length (G_CHECKSUM_MD5); digest = g_alloca (length); if (!boundary) { GChecksum *checksum; /* Generate a fairly random boundary string. */ bgen = g_strdup_printf ("%p:%lu:%lu", (gpointer) multipart, (gulong) getpid (), (gulong) time (NULL)); checksum = g_checksum_new (G_CHECKSUM_MD5); g_checksum_update (checksum, (guchar *) bgen, -1); g_checksum_get_digest (checksum, digest, &length); g_checksum_free (checksum); g_free (bgen); strcpy (bbuf, "=-"); p = bbuf + 2; state = save = 0; p += g_base64_encode_step ( (guchar *) digest, length, FALSE, p, &state, &save); *p = '\0'; boundary = bbuf; } camel_content_type_set_param (cdw->mime_type, "boundary", boundary); }
static gboolean to64 (const gchar *filename, FILE *outfile, GError **error) { GMappedFile *infile; const guchar *in; gchar out[2048]; gint state = 0; gint save = 0; gsize len; gsize bytes; gsize c; infile = g_mapped_file_new (filename, FALSE, error); if (! infile) return FALSE; in = (const guchar *) g_mapped_file_get_contents (infile); len = g_mapped_file_get_length (infile); for (c = 0; c < len;) { gsize step = MIN (1024, len - c); bytes = g_base64_encode_step (in + c, step, TRUE, out, &state, &save); fwrite (out, 1, bytes, outfile); c += step; } bytes = g_base64_encode_close (TRUE, out, &state, &save); fwrite (out, 1, bytes, outfile); g_mapped_file_unref (infile); return TRUE; }
static gchar* _make_hmacsha1_base64_signature(const gchar* base_string, const gchar* key) { gsize digest_len = 100; //sha1 is actually 160 bits guint8 hmac_digest[digest_len]; GHmac* hmac = g_hmac_new(G_CHECKSUM_SHA1, (const guchar*)key, strlen(key)); g_hmac_update(hmac, (const guchar*)base_string, strlen(base_string)); g_hmac_get_digest(hmac, hmac_digest, &digest_len); g_hmac_unref(hmac); gchar* out = g_malloc0((digest_len / 3 + 1) * 4 + 4); gint state = 0; gint save = 0; gchar* p = out; p += g_base64_encode_step(hmac_digest, digest_len, FALSE, p, &state, &save); g_base64_encode_close(FALSE, p, &state, &save); return out; }
static size_t transfer_chunk (void *curl_ptr, TransferBuffer * buffer, Base64Chunk * chunk, size_t block_size, guint * last_chunk) { size_t bytes_to_send; const guchar *data_in = buffer->ptr; size_t data_in_offset = buffer->offset; gint state = chunk->state; gint save = chunk->save; GByteArray *array = chunk->chunk_array; gchar *data_out; bytes_to_send = MIN (block_size, buffer->len); if (bytes_to_send == 0) { bytes_to_send = MIN (block_size, array->len); } /* base64 encode data */ if (buffer->len > 0) { gsize len; gchar *ptr_in; gchar *ptr_out; gsize size_out; gint i; /* if line-breaking is enabled, at least: ((len / 3 + 1) * 4 + 4) / 72 + 1 * bytes of extra space is required. However, additional <CR>'s are required, * thus we need ((len / 3 + 2) * 4 + 4) / 72 + 2 extra bytes. */ size_out = (bytes_to_send / 3 + 1) * 4 + 4 + bytes_to_send + ((bytes_to_send / 3 + 2) * 4 + 4) / 72 + 2; data_out = g_malloc (size_out); len = g_base64_encode_step (data_in + data_in_offset, bytes_to_send, TRUE, data_out, &state, &save); chunk->state = state; chunk->save = save; /* LF->CRLF filter */ ptr_in = ptr_out = data_out; for (i = 0; i < len; i++) { if (*ptr_in == '\n') { *ptr_in = '\r'; g_byte_array_append (array, (guint8 *) ptr_out, ptr_in - ptr_out); g_byte_array_append (array, (guint8 *) "\r\n", strlen ("\r\n")); ptr_out = ptr_in + 1; } ptr_in++; } if (ptr_in - ptr_out) { g_byte_array_append (array, (guint8 *) ptr_out, ptr_in - ptr_out); } g_free (data_out); data_out = NULL; buffer->offset += bytes_to_send; buffer->len -= bytes_to_send; bytes_to_send = MIN (block_size, array->len); memcpy ((guint8 *) curl_ptr, array->data, bytes_to_send); g_byte_array_remove_range (array, 0, bytes_to_send); if (array->len == 0) { *last_chunk = 1; } return bytes_to_send; } /* at this point all data has been encoded */ memcpy ((guint8 *) curl_ptr, array->data, bytes_to_send); g_byte_array_remove_range (array, 0, bytes_to_send); if (array->len == 0) { *last_chunk = 1; } return bytes_to_send; }
static void test_incremental (gboolean line_break, gint length) { char *p; gsize len, decoded_len, max, input_len, block_size; int state, save; guint decoder_save; char *text; guchar *data2; data2 = g_malloc (length); text = g_malloc (length * 4); len = 0; state = 0; save = 0; input_len = 0; while (input_len < length) { block_size = MIN (BLOCK_SIZE, length - input_len); len += g_base64_encode_step (data + input_len, block_size, line_break, text + len, &state, &save); input_len += block_size; } len += g_base64_encode_close (line_break, text + len, &state, &save); if (line_break) max = length * 4 / 3 + length * 4 / (3 * 72) + 7; else max = length * 4 / 3 + 6; if (len > max) { g_print ("Too long encoded length: got %d, expected max %d\n", len, max); exit (1); } decoded_len = 0; state = 0; decoder_save = 0; p = text; while (len > 0) { int chunk_len = MIN (BLOCK_SIZE, len); decoded_len += g_base64_decode_step (p, chunk_len, data2 + decoded_len, &state, &decoder_save); p += chunk_len; len -= chunk_len; } if (decoded_len != length) { g_print ("Wrong decoded length: got %d, expected %d\n", decoded_len, length); exit (1); } if (memcmp (data, data2, length) != 0) { g_print ("Wrong decoded base64 data\n"); exit (1); } g_free (text); g_free (data2); }