static gint lua_util_decode_base64 (lua_State *L) { struct rspamd_lua_text *t; const gchar *s = NULL; gsize inlen, outlen; gboolean zero_copy = FALSE, grab_own = FALSE; gint state = 0; guint save = 0; if (lua_type (L, 1) == LUA_TSTRING) { s = luaL_checklstring (L, 1, &inlen); } else if (lua_type (L, 1) == LUA_TUSERDATA) { t = lua_check_text (L, 1); if (t != NULL) { s = t->start; inlen = t->len; zero_copy = TRUE; if (t->own) { t->own = FALSE; grab_own = TRUE; } } } if (s != NULL) { if (zero_copy) { /* Decode in place */ outlen = g_base64_decode_step (s, inlen, (guchar *)s, &state, &save); t = lua_newuserdata (L, sizeof (*t)); rspamd_lua_setclass (L, "rspamd{text}", -1); t->start = s; t->len = outlen; t->own = grab_own; } else { t = lua_newuserdata (L, sizeof (*t)); rspamd_lua_setclass (L, "rspamd{text}", -1); t->len = (inlen / 4) * 3 + 3; t->start = g_malloc (t->len); outlen = g_base64_decode_step (s, inlen, (guchar *)t->start, &state, &save); t->len = outlen; t->own = TRUE; } } else { lua_pushnil (L); } return 1; }
static void soap_sax_characters (gpointer _ctxt, const xmlChar *ch, gint len) { xmlParserCtxt *ctxt = _ctxt; ESoapMessagePrivate *priv = ctxt->_private; if (priv->steal_fd == -1) xmlSAX2Characters (ctxt, ch, len); else if (!priv->steal_base64) { if (write (priv->steal_fd, (const gchar *) ch, len) != len) { write_err: /* Handle error better */ g_warning ("Failed to write streaming data to file"); } } else { guchar *bdata = g_malloc (len); gsize blen; blen = g_base64_decode_step ((const gchar *) ch, len, bdata, &priv->steal_b64_state, &priv->steal_b64_save); if (write (priv->steal_fd, (const gchar *) bdata, blen) != blen) { g_free (bdata); goto write_err; } g_free (bdata); } }
gchar * kms_utils_generate_fingerprint_from_pem (const gchar * pem) { guint i; gchar *line; guchar *der, *tmp; gchar **lines; gint state = 0; guint save = 0; gsize der_length = 0; GChecksum *checksum; guint8 *digest; gsize digest_length; GString *fingerprint; gchar *ret; if (pem == NULL) { GST_ERROR ("Pem certificate is null"); return NULL; } der = tmp = g_new0 (guchar, (strlen (pem) / 4) * 3 + 3); lines = g_strsplit (pem, "\n", 0); for (i = 0, line = lines[i]; line; line = lines[++i]) { if (line[0] && g_str_has_prefix (line, BEGIN_CERTIFICATE)) { i++; break; } } for (line = lines[i]; line; line = lines[++i]) { if (line[0] && g_str_has_prefix (line, END_CERTIFICATE)) { break; } tmp += g_base64_decode_step (line, strlen (line), tmp, &state, &save); } der_length = tmp - der; checksum = g_checksum_new (G_CHECKSUM_SHA256); digest_length = g_checksum_type_get_length (G_CHECKSUM_SHA256); digest = g_new (guint8, digest_length); g_checksum_update (checksum, der, der_length); g_checksum_get_digest (checksum, digest, &digest_length); fingerprint = g_string_new (NULL); for (i = 0; i < digest_length; i++) { if (i) g_string_append (fingerprint, ":"); g_string_append_printf (fingerprint, "%02X", digest[i]); } ret = g_string_free (fingerprint, FALSE); g_free (digest); g_checksum_free (checksum); g_free (der); g_strfreev (lines); return ret; }
/** Convert Base64 to pixbuf * @param b64 Base64 encoded data */ GdkPixbuf * pixbuf_decode_base64 (const gchar *b64) { /* see lib/prop_pixbuf.c(data_pixbuf) for a very similar implementation */ GdkPixbuf *pixbuf = NULL; GdkPixbufLoader *loader; GError *error = NULL; loader = gdk_pixbuf_loader_new (); if (loader) { gint state = 0; guint save = 0; # define BUF_SIZE 4096 guchar buf[BUF_SIZE]; gchar *in = (gchar *)b64; /* direct access, not involving another xmlStrDup/xmlFree */ gssize len = strlen (b64); do { gsize step = g_base64_decode_step (in, len > BUF_SIZE ? BUF_SIZE : len, buf, &state, &save); if (!gdk_pixbuf_loader_write (loader, buf, step, &error)) break; in += BUF_SIZE; len -= BUF_SIZE; } while (len > 0); if (gdk_pixbuf_loader_close (loader, error ? NULL : &error)) { GdkPixbufFormat *format = gdk_pixbuf_loader_get_format (loader); gchar *format_name = gdk_pixbuf_format_get_name (format); gchar **mime_types = gdk_pixbuf_format_get_mime_types (format); dia_log_message ("Loaded pixbuf from '%s' with '%s'\n", format_name, mime_types[0]); pixbuf = g_object_ref (gdk_pixbuf_loader_get_pixbuf (loader)); /* attach the mime-type to the pixbuf */ g_object_set_data_full (G_OBJECT (pixbuf), "mime-type", g_strdup (mime_types[0]), (GDestroyNotify)g_free); g_strfreev (mime_types); g_free (format_name); } else { message_warning (_("Failed to load image form diagram:\n%s"), error->message); g_error_free (error); } g_object_unref (loader); } return pixbuf; # undef BUF_SIZE }
GdkPixbuf * data_pixbuf (DataNode data) { GdkPixbuf *pixbuf = NULL; GdkPixbufLoader *loader; GError *error = NULL; AttributeNode attr = composite_find_attribute(data, "data"); loader = gdk_pixbuf_loader_new (); if (loader) { xmlNode *node = attribute_first_data (attr); gint state = 0; guint save = 0; # define BUF_SIZE 4096 guchar buf[BUF_SIZE]; gchar *in = NULL; /* direct access, not involving another xmlStrDup/xmlFree */ gssize len = 0; if (node->children && xmlStrcmp (node->children->name, (const xmlChar*)"text") == 0) { in = (gchar *)node->children->content; len = strlen ((char *)in); } do { gsize step = g_base64_decode_step (in, len > BUF_SIZE ? BUF_SIZE : len, buf, &state, &save); if (!gdk_pixbuf_loader_write (loader, buf, step, &error)) break; in += BUF_SIZE; len -= BUF_SIZE; } while (len > 0); if (gdk_pixbuf_loader_close (loader, error ? NULL : &error)) { pixbuf = g_object_ref (gdk_pixbuf_loader_get_pixbuf (loader)); } else { message_warning (_("Failed to load image form diagram:\n%s"), error->message); g_error_free (error); } g_object_unref (loader); } # undef BUF_SIZE return pixbuf; }
static gboolean validate_key (const char *key) { guchar buf[18]; int state = 0; guint save = 0; /* The spec requires us to check that the key is "a * base64-encoded value that, when decoded, is 16 bytes in * length". */ if (strlen (key) != 24) return FALSE; if (g_base64_decode_step (key, 24, buf, &state, &save) != 16) return FALSE; return TRUE; }
static gchar * generate_fingerprint_from_pem (const gchar * pem) { guint i; gchar *line; guchar *der, *tmp; gchar **lines; gint state = 0; guint save = 0; gsize der_length = 0; GChecksum *checksum; guint8 *digest; gsize digest_length; GString *fingerprint; gchar *ret; der = tmp = g_new0 (guchar, (strlen (pem) / 4) * 3 + 3); lines = g_strsplit (pem, "\n", 0); for (i = 0, line = lines[i]; line; line = lines[++i]) { if (line[0] && !g_str_has_prefix (line, "-----")) tmp += g_base64_decode_step (line, strlen (line), tmp, &state, &save); } der_length = tmp - der; checksum = g_checksum_new (G_CHECKSUM_SHA256); digest_length = g_checksum_type_get_length (G_CHECKSUM_SHA256); digest = g_new (guint8, digest_length); g_checksum_update (checksum, der, der_length); g_checksum_get_digest (checksum, digest, &digest_length); fingerprint = g_string_new (NULL); for (i = 0; i < digest_length; i++) { if (i) g_string_append (fingerprint, ":"); g_string_append_printf (fingerprint, "%02X", digest[i]); } ret = g_string_free (fingerprint, FALSE); g_free (digest); g_checksum_free (checksum); g_free (der); g_strfreev (lines); return ret; }
void got_dtls_certificate(GObject *media_session, GParamSpec *pspec, gpointer user_data) { guint i; gchar *pem, *line; guchar *der, *tmp; gchar **lines; gint state = 0; guint save = 0; gsize der_length = 0; GChecksum *checksum; guint8 *digest; gsize digest_length; GString *fingerprint; g_object_get(media_session, "dtls-certificate", &pem, NULL); der = tmp = g_new0(guchar, (strlen(pem) / 4) * 3 + 3); lines = g_strsplit(pem, "\n", 0); for (i = 0, line = lines[i]; line; line = lines[++i]) { if (line[0] && !g_str_has_prefix(line, "-----")) tmp += g_base64_decode_step(line, strlen(line), tmp, &state, &save); } der_length = tmp - der; checksum = g_checksum_new(G_CHECKSUM_SHA256); digest_length = g_checksum_type_get_length(G_CHECKSUM_SHA256); digest = g_new(guint8, digest_length); g_checksum_update(checksum, der, der_length); g_checksum_get_digest(checksum, digest, &digest_length); fingerprint = g_string_new(NULL); for (i = 0; i < digest_length; i++) { if (i) g_string_append(fingerprint, ":"); g_string_append_printf(fingerprint, "%02X", digest[i]); } gchar *fprint = g_string_free(fingerprint, FALSE); got_dtls_certificate_go(OWR_SESSION(media_session), fprint); g_free(fprint); g_free(digest); g_checksum_free(checksum); g_free(der); g_strfreev(lines); }
static GBytes * base64_decode (GBytes *bytes) { gconstpointer data; guchar *decoded; gsize length; gint state = 0; guint 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 used to avoid calling g_malloc0(0), and hence returning NULL */ decoded = g_malloc0 ((length / 4) * 3 + 3); length = g_base64_decode_step (data, length, decoded, &state, &save); return g_bytes_new_take (decoded, length); }
/** Convert Base64 to pixbuf * @param b64 Base64 encoded data */ GdkPixbuf * pixbuf_decode_base64 (const gchar *b64) { /* see lib/prop_pixbuf.c(data_pixbuf) for a very similiar implementation */ GdkPixbuf *pixbuf = NULL; GdkPixbufLoader *loader; GError *error = NULL; loader = gdk_pixbuf_loader_new (); if (loader) { gint state = 0; guint save = 0; # define BUF_SIZE 4096 guchar buf[BUF_SIZE]; gchar *in = (gchar *)b64; /* direct access, not involving another xmlStrDup/xmlFree */ gssize len = strlen (b64); do { gsize step = g_base64_decode_step (in, len > BUF_SIZE ? BUF_SIZE : len, buf, &state, &save); if (!gdk_pixbuf_loader_write (loader, buf, step, &error)) break; in += BUF_SIZE; len -= BUF_SIZE; } while (len > 0); if (gdk_pixbuf_loader_close (loader, error ? NULL : &error)) { pixbuf = g_object_ref (gdk_pixbuf_loader_get_pixbuf (loader)); } else { message_warning (_("Failed to load image form diagram:\n%s"), error->message); g_error_free (error); } g_object_unref (loader); } return pixbuf; # undef BUF_SIZE }
GkmDataResult gkm_ssh_openssh_parse_public_key (gconstpointer input, gsize n_data, gcry_sexp_t *sexp, gchar **comment) { EggBuffer buf; const guchar *at; guchar *decoded; gsize n_decoded; gsize offset; gchar *val; gboolean ret; gint state, algo; guint save; const guchar *data = input; g_return_val_if_fail (data, FALSE); g_return_val_if_fail (sexp, FALSE); /* Look for a key line */ for (;;) { /* Eat space at the front */ while (n_data > 0 && g_ascii_isspace (data[0])) { ++data; --n_data; } /* Not a comment or blank line? Then parse... */ if (data[0] != '#') break; /* Skip to the next line */ at = memchr (data, '\n', n_data); if (!at) return GKM_DATA_UNRECOGNIZED; at += 1; n_data -= (at - data); data = at; } /* Limit to use only the first line */ at = memchr (data, '\n', n_data); if (at != NULL) n_data = at - data; /* Find the first space */ at = memchr (data, ' ', n_data); if (!at) { g_message ("SSH public key missing space"); return GKM_DATA_UNRECOGNIZED; } /* Parse the key type */ val = g_strndup ((gchar*)data, at - data); algo = keytype_to_algo (val); if (!algo) { /* A number usually means an SSH1 key, just quietly ignore */ if (atoi (val) == 0) g_message ("Unsupported or unknown SSH key algorithm: %s", val); } g_free (val); if (!algo) return GKM_DATA_UNRECOGNIZED; /* Skip more whitespace */ n_data -= (at - data); data = at; while (n_data > 0 && (data[0] == ' ' || data[0] == '\t')) { ++data; --n_data; } /* Find the next whitespace, or the end */ at = memchr (data, ' ', n_data); if (at == NULL) at = data + n_data; /* Decode the base64 key */ save = state = 0; decoded = g_malloc (n_data * 3 / 4); n_decoded = g_base64_decode_step ((gchar*)data, n_data, decoded, &state, &save); /* Parse the actual key */ egg_buffer_init_static (&buf, decoded, n_decoded); offset = 0; ret = read_public (&buf, &offset, sexp, NULL); g_free (decoded); if (!ret) { g_message ("failed to parse base64 part of SSH key"); return GKM_DATA_FAILURE; } /* Skip more whitespace */ n_data -= (at - data); data = at; while (n_data > 0 && (data[0] == ' ' || data[0] == '\t')) { ++data; --n_data; } /* If there's data left, its the comment */ if (comment) *comment = n_data ? g_strndup ((gchar*)data, n_data) : NULL; return GKM_DATA_SUCCESS; }
static GHashTable* inf_gtk_certificate_manager_load_known_hosts(InfGtkCertificateManager* mgr, GError** error) { InfGtkCertificateManagerPrivate* priv; GHashTable* table; gchar* content; gsize size; GError* local_error; gchar* out_buf; gsize out_buf_len; gchar* pos; gchar* prev; gchar* next; gchar* sep; gsize len; gsize out_len; gint base64_state; guint base64_save; gnutls_datum_t data; gnutls_x509_crt_t cert; int res; priv = INF_GTK_CERTIFICATE_MANAGER_PRIVATE(mgr); table = g_hash_table_new_full( g_str_hash, g_str_equal, g_free, (GDestroyNotify)gnutls_x509_crt_deinit ); local_error = NULL; g_file_get_contents(priv->known_hosts_file, &content, &size, &local_error); if(local_error != NULL) { if(local_error->domain == G_FILE_ERROR && local_error->code == G_FILE_ERROR_NOENT) { return table; } g_propagate_prefixed_error( error, local_error, _("Failed to open known hosts file \"%s\": "), priv->known_hosts_file ); g_hash_table_destroy(table); return NULL; } out_buf = NULL; out_buf_len = 0; prev = content; for(prev = content; prev != NULL; prev = next) { pos = strchr(prev, '\n'); next = NULL; if(pos == NULL) pos = content + size; else next = pos + 1; sep = inf_gtk_certificate_manager_memrchr(prev, ':', pos - prev); if(sep == NULL) continue; /* ignore line */ *sep = '\0'; if(g_hash_table_lookup(table, prev) != NULL) { g_set_error( error, g_quark_from_static_string("INF_GTK_CERTIFICATE_MANAGER_ERROR"), INF_GTK_CERTIFICATE_MANAGER_ERROR_DUPLICATE_HOST_ENTRY, _("Certificate for host \"%s\" appears twice in " "known hosts file \"%s\""), prev, priv->known_hosts_file ); g_hash_table_destroy(table); g_free(out_buf); g_free(content); return NULL; } /* decode base64, import DER certificate */ len = (pos - (sep + 1)); out_len = len * 3 / 4; if(out_len > out_buf_len) { out_buf = g_realloc(out_buf, out_len); out_buf_len = out_len; } base64_state = 0; base64_save = 0; out_len = g_base64_decode_step( sep + 1, len, out_buf, &base64_state, &base64_save ); cert = NULL; res = gnutls_x509_crt_init(&cert); if(res == GNUTLS_E_SUCCESS) { data.data = out_buf; data.size = out_len; res = gnutls_x509_crt_import(cert, &data, GNUTLS_X509_FMT_DER); } if(res != GNUTLS_E_SUCCESS) { inf_gnutls_set_error(&local_error, res); g_propagate_prefixed_error( error, local_error, _("Failed to read certificate for host \"%s\" from " "known hosts file \"%s\": "), prev, priv->known_hosts_file ); if(cert != NULL) gnutls_x509_crt_deinit(cert); g_hash_table_destroy(table); g_free(out_buf); g_free(content); return NULL; } g_hash_table_insert(table, g_strdup(prev), cert); } g_free(out_buf); g_free(content); return table; }
static int parse_attribute_crypto(struct sdp_attribute *output) { PARSE_DECL; char *endp; struct attribute_crypto *c; int salt_key_len, enc_salt_key_len; int b64_state = 0; unsigned int b64_save = 0; gsize ret; str s; u_int32_t u32; const char *err; output->attr = ATTR_CRYPTO; PARSE_INIT; EXTRACT_TOKEN(u.crypto.tag_str); EXTRACT_TOKEN(u.crypto.crypto_suite_str); EXTRACT_TOKEN(u.crypto.key_params_str); c = &output->u.crypto; c->tag = strtoul(c->tag_str.s, &endp, 10); err = "invalid 'tag'"; if (endp == c->tag_str.s) goto error; c->crypto_suite = crypto_find_suite(&c->crypto_suite_str); err = "unknown crypto suite"; if (!c->crypto_suite) goto error; salt_key_len = c->crypto_suite->master_key_len + c->crypto_suite->master_salt_len; enc_salt_key_len = ceil((double) salt_key_len * 4.0/3.0); err = "invalid key parameter length"; if (c->key_params_str.len < 7 + enc_salt_key_len) goto error; err = "unknown key method"; if (strncasecmp(c->key_params_str.s, "inline:", 7)) goto error; c->key_base64_str = c->key_params_str; str_shift(&c->key_base64_str, 7); ret = g_base64_decode_step(c->key_base64_str.s, enc_salt_key_len, (guchar *) c->key_salt_buf, &b64_state, &b64_save); err = "invalid base64 encoding"; if (ret != salt_key_len) goto error; c->master_key.s = c->key_salt_buf; c->master_key.len = c->crypto_suite->master_key_len; c->salt.s = c->master_key.s + c->master_key.len; c->salt.len = c->crypto_suite->master_salt_len; c->lifetime_str = c->key_params_str; str_shift(&c->lifetime_str, 7 + enc_salt_key_len); if (c->lifetime_str.len >= 2) { err = "invalid key parameter syntax"; if (c->lifetime_str.s[0] != '|') goto error; str_shift(&c->lifetime_str, 1); str_chr_str(&c->mki_str, &c->lifetime_str, '|'); if (!c->mki_str.s) { if (str_chr(&c->lifetime_str, ':')) { c->mki_str = c->lifetime_str; c->lifetime_str = STR_NULL; } } else { c->lifetime_str.len = c->mki_str.s - c->lifetime_str.s; str_shift(&c->mki_str, 1); } } else c->lifetime_str = STR_NULL; if (c->lifetime_str.s) { if (c->lifetime_str.len >= 3 && !memcmp(c->lifetime_str.s, "2^", 2)) { c->lifetime = strtoull(c->lifetime_str.s + 2, NULL, 10); err = "invalid key lifetime"; if (!c->lifetime || c->lifetime > 64) goto error; c->lifetime = 1ULL << c->lifetime; } else c->lifetime = strtoull(c->lifetime_str.s, NULL, 10); err = "invalid key lifetime"; if (!c->lifetime || c->lifetime > c->crypto_suite->srtp_lifetime #ifdef STRICT_SDES_KEY_LIFETIME || c->lifetime > c->crypto_suite->srtcp_lifetime #endif ) goto error; } if (c->mki_str.s) { str_chr_str(&s, &c->mki_str, ':'); err = "invalid MKI specification"; if (!s.s) goto error; u32 = htonl(strtoul(c->mki_str.s, NULL, 10)); c->mki_len = strtoul(s.s + 1, NULL, 10); err = "MKI too long"; if (c->mki_len > sizeof(c->mki)) goto error; memset(c->mki, 0, c->mki_len); if (sizeof(u32) >= c->mki_len) memcpy(c->mki, ((void *) &u32) + (sizeof(u32) - c->mki_len), c->mki_len); else memcpy(c->mki + (c->mki_len - sizeof(u32)), &u32, sizeof(u32)); } while (extract_token(&start, end, &s) == 0) { if (!str_cmp(&s, "UNENCRYPTED_SRTCP")) c->unencrypted_srtcp = 1; else if (!str_cmp(&s, "UNENCRYPTED_SRTP")) c->unencrypted_srtp = 1; else if (!str_cmp(&s, "UNAUTHENTICATED_SRTP")) c->unauthenticated_srtp = 1; } return 0; error: ilog(LOG_ERROR, "Failed to parse a=crypto attribute: %s", err); return -1; }
/* called from the GMarkupParser */ static void text_handler (GMarkupParseContext *markup_context, const gchar *text, gsize text_len, gpointer user_data, GError **error) { XMPParseContext *context = user_data; switch (context->state) { case STATE_INSIDE_PROPERTY: if (! is_whitespace_string (text)) add_property_value (context, XMP_PTYPE_TEXT, NULL, g_strndup (text, text_len)); break; case STATE_INSIDE_STRUCT_ELEMENT: case STATE_INSIDE_ALT_LI: case STATE_INSIDE_BAG_LI: case STATE_INSIDE_SEQ_LI: if (! is_whitespace_string (text)) update_property_value (context, g_strndup (text, text_len)); break; case STATE_INSIDE_ALT_LI_RSC_IMG: { size_t len, max_size; guchar *decoded; gint decoded_size; gint state; guint save; #ifdef DEBUG_XMP_PARSER /* g_print ("XMP: Pushing text:\n%s\n", text); */ #endif len = text_len - text_len; max_size = (len / 4) * 3 + 3; decoded = g_malloc (max_size); state = 0; save = 0; decoded_size = g_base64_decode_step (text, text_len, decoded, &state, &save); #ifdef DEBUG_XMP_PARSER if (decoded_size > 0) { /* FIXME: remove this debugging code */ /* FILE *ttt; ttt = fopen ("/tmp/xmp-thumb.jpg", "wb"); fwrite (decoded, decoded_size, 1, ttt); fclose (ttt); */ g_print ("XMP: Thumb text len: %d (1/4 = %d)\nMax size: %d\nUsed size: %d\n", (int) text_len, (int) text_len / 4, max_size, decoded_size); } #endif if (decoded_size > 0) { gint *size_p; size_p = g_new (gint, 1); *size_p = decoded_size; add_property_value (context, XMP_PTYPE_ALT_THUMBS, (gchar *) size_p, (gchar *) decoded); } else add_property_value (context, XMP_PTYPE_ALT_THUMBS, NULL, NULL); } break; case STATE_INSIDE_QDESC_VALUE: if (! is_whitespace_string (text)) { if (context->saved_state == STATE_INSIDE_PROPERTY) add_property_value (context, XMP_PTYPE_TEXT, NULL, g_strndup (text, text_len)); else update_property_value (context, g_strndup (text, text_len)); } break; case STATE_INSIDE_QDESC_QUAL: #ifdef DEBUG_XMP_PARSER g_print ("ignoring qualifier for part of \"%s\"[]: \"%.*s\"\n", context->property, (int)text_len, text); #endif /* FIXME: notify the user? add a way to collect qualifiers? */ break; case STATE_SKIPPING_UNKNOWN_ELEMENTS: case STATE_SKIPPING_IGNORED_ELEMENTS: break; default: if (! is_whitespace_string (text)) parse_error (context, error, XMP_ERROR_INVALID_CONTENT, _("The current element (<%s>) cannot contain text"), g_markup_parse_context_get_element (markup_context)); break; } }
static GInputStream * soup_request_data_send (SoupRequest *request, GCancellable *cancellable, GError **error) { SoupRequestData *data = SOUP_REQUEST_DATA (request); SoupURI *uri = soup_request_get_uri (request); GInputStream *memstream; const char *comma, *start, *end; gboolean base64 = FALSE; char *uristr; uristr = soup_uri_to_string (uri, FALSE); start = uristr + 5; comma = strchr (start, ','); if (comma && comma != start) { /* Deal with MIME type / params */ if (comma > start + BASE64_INDICATOR_LEN && !g_ascii_strncasecmp (comma - BASE64_INDICATOR_LEN, BASE64_INDICATOR, BASE64_INDICATOR_LEN)) { end = comma - BASE64_INDICATOR_LEN; base64 = TRUE; } else end = comma; if (end != start) { char *encoded_content_type = g_strndup (start, end - start); if (base64) data->priv->content_type = encoded_content_type; else { data->priv->content_type = soup_uri_decode (encoded_content_type); g_free (encoded_content_type); } } } memstream = g_memory_input_stream_new (); if (comma) start = comma + 1; if (*start) { guchar *buf; if (base64) { int inlen, state = 0; guint save = 0; inlen = strlen (start); buf = g_malloc0 (inlen * 3 / 4 + 3); data->priv->content_length = g_base64_decode_step (start, inlen, buf, &state, &save); if (state != 0) { g_free (buf); goto fail; } } else { buf = (guchar *) soup_uri_decode (start); data->priv->content_length = strlen ((const char *) buf); } g_memory_input_stream_add_data (G_MEMORY_INPUT_STREAM (memstream), buf, data->priv->content_length, g_free); } g_free (uristr); return memstream; fail: g_free (uristr); g_set_error (error, SOUP_REQUESTER_ERROR, SOUP_REQUESTER_ERROR_BAD_URI, _("Unable to decode URI: %s"), start); g_object_unref (memstream); return NULL; }
static gboolean pem_parse_block (const gchar *data, gsize n_data, guchar **decoded, gsize *n_decoded, GHashTable **headers) { const gchar *x, *hbeg, *hend; const gchar *p, *end; gint state = 0; guint save = 0; g_assert (data); g_assert (n_data); g_assert (decoded); g_assert (n_decoded); p = data; end = p + n_data; hbeg = hend = NULL; /* Try and find a pair of blank lines with only white space between */ while (hend == NULL) { x = memchr (p, '\n', end - p); if (!x) break; ++x; while (isspace (*x)) { /* Found a second line, with only spaces between */ if (*x == '\n') { hbeg = data; hend = x; break; /* Found a space between two lines */ } else { ++x; } } /* Try next line */ p = x; } /* Headers found? */ if (hbeg && hend) { data = hend; n_data = end - data; } *n_decoded = (n_data * 3) / 4 + 1; if (egg_secure_check (data)) *decoded = egg_secure_alloc (*n_decoded); else *decoded = g_malloc0 (*n_decoded); g_return_val_if_fail (*decoded, FALSE); *n_decoded = g_base64_decode_step (data, n_data, *decoded, &state, &save); if (!*n_decoded) { egg_secure_free (*decoded); return FALSE; } if (headers && hbeg && hend) parse_header_lines (hbeg, hend, headers); return TRUE; }
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); }