Exemple #1
0
int main(int argc, char** argv) {

	if (argc < 2) {
		usage(argv[0]);
		return -1;
	}

	int ch = 0;
	char *out = NULL;
	int len = -1;

	while ((ch = getopt(argc, argv, "e:d:h")) != -1) {

		switch (ch) {
			case 'e': {

				len = base64_encode_alloc(optarg, strlen(optarg), &out);
				printf("source:%s , encoded:%s , encode_len:%d\n", optarg, out,
						len);
				out = NULL;
				len = -1;
			}
				break;

			case 'd': {
				base64_decode_alloc(optarg, strlen(optarg), &out, &len);
				printf("source:%s , encoded:%s , decode_len:%d\n", optarg, out,
						len);
				out = NULL;
				len = -1;
			}
				break;

			case 'h': {
				usage(argv[0]);
			}
				break;

			case '?': {
				usage(argv[0]);
			}
				break;
		}
	}

	return 0;
}
Exemple #2
0
/*!
 * \brief Convert Base64 encoded number into OpenSSL BIGNUM format.
 */
BIGNUM *knot_b64_to_bignum(const char *input)
{
	size_t size = strlen(input);
	uint8_t *decoded;
	int32_t decoded_size;
	BIGNUM *result;

	decoded_size = base64_decode_alloc((uint8_t *)input, size, &decoded);
	if (decoded_size < 0) {
		return NULL;
	}

	result = BN_bin2bn((unsigned char *)decoded, (int)decoded_size, NULL);
	free(decoded);

	return result;
}
Exemple #3
0
data_buffer mini_base64_decode(char *data, size_t len)
{
	data_buffer						retval;
	struct base64_decode_context	ctx;
	size_t							new_len;
	
	base64_decode_ctx_init(&ctx);

	if (!base64_decode_alloc(&ctx, data, len, &(retval.data), &new_len))
	{
		retval.data = NULL;
		retval.len = 0;
	}
	retval.len = new_len;
	
	return retval;
}
Exemple #4
0
ssize_t
base64url_decode_alloc (const uint8_t *data, size_t l, char **out)
{
    size_t i, s, pad;
    char *burl;
    size_t len;

    assert(NULL != data);

    len = strnlen ((const char *)data, l);

    pad = len + (4 - len % 4) % 4;

    assert (pad >= len);

    burl = malloc (pad + 1);
    assert (NULL != burl);
    memset (burl, 0, pad + 1);

    strncpy (burl, (const char *)data, len);

    for (i = 0; i < len; i++)
    {
        if ('-' == *(burl+i))
            *(burl+i) = '+';
        else if ('_' == *(burl+i))
            *(burl+i) = '/';
    }

    for (i = 0; i < (pad - len); i++)
    {
        burl[len + i] = '=';
    }

    if (!base64_decode_alloc (burl, pad, out, &s))
    {
        s = -1;
    }

    free (burl);

    return s;
}
Exemple #5
0
int flib_drawnmapdata_from_netmsg(char *netmsg, uint8_t** outbuf, size_t *outlen) {
    int result = -1;

    // First step: base64 decoding
    char *base64decout = NULL;
    size_t base64declen;
    bool ok = base64_decode_alloc(netmsg, strlen(netmsg), &base64decout, &base64declen);
    if(ok && base64declen>3) {
        // Second step: unzip with the QCompress header. That header is just a big-endian
        // uint32 indicating the length of the uncompressed data.
        uint8_t *ubyteBuf = (uint8_t*)base64decout;
        uint32_t unzipLen =
                (((uint32_t)ubyteBuf[0])<<24)
                + (((uint32_t)ubyteBuf[1])<<16)
                + (((uint32_t)ubyteBuf[2])<<8)
                + ubyteBuf[3];
        if(unzipLen==0) {
            *outbuf = NULL;
            *outlen = 0;
            result = 0;
        } else {
            uint8_t *out = flib_malloc(unzipLen);
            if(out) {
                uLongf actualUnzipLen = unzipLen;
                int resultcode = uncompress(out, &actualUnzipLen, (Bytef*)(base64decout+4), base64declen-4);
                if(resultcode == Z_OK) {
                    *outbuf = out;
                    *outlen = actualUnzipLen;
                    out = NULL;
                    result = 0;
                } else {
                    flib_log_e("Uncompressing drawn map failed. Code: %i", resultcode);
                }
            }
            free(out);
        }
    } else {
        flib_log_e("base64 decoding of drawn map failed.");
    }
    free(base64decout);
    return result;
}
Exemple #6
0
static bool
cmdSecretSetValue(vshControl *ctl, const vshCmd *cmd)
{
    virSecretPtr secret;
    size_t value_size;
    const char *base64 = NULL;
    char *value;
    int res;
    bool ret = false;

    if (!(secret = virshCommandOptSecret(ctl, cmd, NULL)))
        return false;

    if (vshCommandOptStringReq(ctl, cmd, "base64", &base64) < 0)
        goto cleanup;

    if (!base64_decode_alloc(base64, strlen(base64), &value, &value_size)) {
        vshError(ctl, "%s", _("Invalid base64 data"));
        goto cleanup;
    }
    if (value == NULL) {
        vshError(ctl, "%s", _("Failed to allocate memory"));
        goto cleanup;
    }

    res = virSecretSetValue(secret, (unsigned char *)value, value_size, 0);
    memset(value, 0, value_size);
    VIR_FREE(value);

    if (res != 0) {
        vshError(ctl, "%s", _("Failed to set secret value"));
        goto cleanup;
    }
    vshPrintExtra(ctl, "%s", _("Secret value set\n"));
    ret = true;

 cleanup:
    virSecretFree(secret);
    return ret;
}
Exemple #7
0
void
test (Shishi * handle)
{
  Shishi_asn1 req, rep;
  char *reqder, *repder;
  size_t reqderlen, repderlen;
  int rc;
  uint32_t nonce;

  if (!base64_decode_alloc (asreq, strlen (asreq), &reqder, &reqderlen))
    fail ("base64 req\n");

  if (!base64_decode_alloc (asreppart, strlen (asreppart), &repder, &repderlen))
    fail ("base64 rep\n");

  req = shishi_der2asn1_asreq (handle, reqder, reqderlen);
  if (!req)
    fail ("der2asn1 req\n");

  rep = shishi_der2asn1_encasreppart (handle, repder, repderlen);
  if (!rep)
    fail ("der2asn1 rep\n");

  if (debug)
    {
      shishi_kdcreq_print (handle, stdout, req);
      shishi_enckdcreppart_print (handle, stdout, rep);
    }

  /* Read and check req */

  rc = shishi_asn1_read_uint32 (handle, req, "req-body.nonce", &nonce);
  if (rc)
    fail ("shishi_asn1_read_uint32\n");

  printf ("req nonce: %x\n", nonce);

  if (nonce != 0x09575283)
    fail ("nonce mismatch low\n");

  rc = shishi_kdcreq_nonce (handle, req, &nonce);
  if (rc)
    fail ("shishi_kdcreq_nonce\n");

  printf ("req nonce: %x\n", nonce);

  if (nonce != 0x09575283)
    fail ("nonce mismatch high");

  /* Read and check rep */

  rc = shishi_asn1_read_uint32 (handle, rep, "nonce", &nonce);
  if (rc)
    fail ("read rep uint32");

  printf ("old rep nonce: %x\n", nonce);

  if (nonce != 0x7fffffff)
    fail ("nonce mismatch high");

  /* Copy nonce. */

  rc = shishi_kdc_copy_nonce (handle, req, rep);
  if (rc)
    fail ("shishi_kdc_copy_nonce\n");

  /* Read and check rep */

  rc = shishi_asn1_read_uint32 (handle, rep, "nonce", &nonce);
  if (rc)
    fail ("read rep uint32");

  printf ("new rep nonce: %x\n", nonce);

  if (nonce != 0x09575283)
    fail ("nonce mismatch high");

  free (reqder);
  free (repder);

  shishi_asn1_done (handle, req);
  shishi_asn1_done (handle, rep);
}
Exemple #8
0
Trace * Trace::load_project_file(const char * filename)
{

	XMLBZIP2_reader reader;
	
	xmlDocPtr doc = reader.xmlReadDoc(filename);
	
    if (doc == NULL) {
        fprintf(stderr, "Failed to parse %s\n", filename);
		return NULL;
    }
	
	// Todo - make it actually load the architecture on demand
	Trace * t = new Trace(new ARMArchitecture());
	xmlNodePtr root_element = xmlDocGetRootElement(doc);
	
	xmlNodePtr memories_n = findChild(root_element, "memblocks");
	if (!memories_n)
	{
		printf("could not find memblocks section, aborting!\n");
		return NULL;
	}
		
	xmlNodePtr memory_n = findChild(memories_n, "memory");
	if (!memory_n)
	{
		printf("could not load memory, aborting!\n");
		return NULL;
	}
	

	xmlNodePtr memory_base_n = findChild(memory_n, "base");
	if (!memory_base_n)
	{
		printf("could not find memory base address, aborting!\n");
		return NULL;
	}
	address_t base_addr = strtoul((char *) xmlNodeGetContent(memory_base_n), NULL, 16);
	
	
	xmlNodePtr memory_data_n = findChild(memory_n, "data");
	if (!memory_n)
	{
		printf("could not find memory data, aborting!\n");
		return NULL;
	}
	char * base64_content = (char*)xmlNodeGetContent(memory_data_n);
	int base64_len = strlen(base64_content);
	
	char * code_buf;
	size_t code_len;
	
	bool ok = base64_decode_alloc (base64_content, base64_len, &code_buf, &code_len);
	xmlFree(base64_content);
	if (!ok)
	{
		printf("could not parse memory data, aborting!\n");
		return NULL;
	}
	MemSegment * m = new MemSegment(base_addr, code_len, code_buf);
	t->addSegment(m);
	
	free(code_buf);
	xmlNodePtr instructions_n = findChild(root_element,  "instructions");
	
	if (instructions_n)
		for(xmlNodePtr node_a = instructions_n->children; node_a != NULL; node_a = node_a->next) {
			u32 addr;
			u32 opcode;
			
			bool good = false;
			bool opcodeset = false;
			//printf("node %s\n", node_a->name);
			
			for(xmlNodePtr node_b = node_a->children; node_b != NULL; node_b = node_b->next) {
				char * content = (char *) xmlNodeGetContent(node_b);
				if (!content)
					continue;
				
				if (xmlStrcmp(node_b->name, BAD_CAST "addr") == 0)
				{
					good = true;
					addr = strtoul(content, NULL, 16);
				}
				else if (xmlStrcmp(node_b->name, BAD_CAST "opcode") == 0)
				{
					opcode = strtoul(content, NULL, 16);
					opcodeset = true;
				}
				xmlFree(content);
			}
			if (!opcodeset)
				opcode = t->ldw(addr);
			
			if (good)
			{
				// fixme
				Instruction * inst = t->m_arch->create_instruction(t, addr);//new Instruction(t, addr, opcode);
				
				t->insert_memlocd(inst);
			} else {
				printf("Instruction was missing addr!\n");
			}
		}
	else
		printf("warning, no Instruction content found for xml doc\n");
	
	xmlNodePtr symbols_n = findChild(root_element, "symbols");
	if (symbols_n)
	{
		for(xmlNodePtr node_a = symbols_n->children; node_a != NULL; node_a = node_a->next) {
			std::string name;
			u32 addr;
			
			bool goodname = false;
			bool goodaddr = false;
			
			for(xmlNodePtr node_b = node_a->children; node_b != NULL; node_b = node_b->next) {
				char * content = (char *) xmlNodeGetContent(node_b);
				if (!content)
					continue;
				
				if (xmlStrcmp(node_b->name, BAD_CAST "addr") == 0)
				{
					goodaddr = true;
					addr = strtoul(content, NULL, 16);
				}
				else if (xmlStrcmp(node_b->name, BAD_CAST "name") == 0)
				{
					name = content;
					goodname = true;
				}
	
				xmlFree(content);
			}

			if (goodname && goodaddr)
				t->create_sym(name.c_str(), addr);
			else
				printf("Symbol did not load %d %d\n", goodname, goodaddr);
		}
	} else {
		printf("Warning - no symbol section found in saved file!\n");
	}
	
	xmlNodePtr xrefs_n = findChild(root_element, "xrefs");
	if (xrefs_n)
	{
		for(xmlNodePtr node_a = xrefs_n->children; node_a != NULL; node_a = node_a->next) {
			u32 srcaddr;
			u32 dstaddr;
			u32 type;
			
			bool goodsrc = false;
			bool gooddst = false;
			bool goodtype = false;
			
			for(xmlNodePtr node_b = node_a->children; node_b != NULL; node_b = node_b->next) {
				char * content = (char *) xmlNodeGetContent(node_b);
				if (!content)
					continue;
				
				if (xmlStrcmp(node_b->name, BAD_CAST "srcaddr") == 0)
				{
					goodsrc = true;
					srcaddr = strtoul(content, NULL, 16);
				} else if (xmlStrcmp(node_b->name, BAD_CAST "dstaddr") == 0)
				{
					gooddst = true;
					dstaddr = strtoul(content, NULL, 16);
				} else if (xmlStrcmp(node_b->name, BAD_CAST "type") == 0)
				{
					goodtype = true;
					type = strtoul(content, NULL, 16);
				}
	
				xmlFree(content);
			}
			
			if (goodsrc && gooddst && goodtype)
				t->create_xref(srcaddr, dstaddr, type);
			else
				printf("Xref did not load %d %d %d\n", goodsrc, gooddst, goodtype);
		}
	} else {
		printf("Warning - no xref section found in saved file!\n");
	}
	
	
    xmlFreeDoc(doc);
	
	return t;
}
Exemple #9
0
static bool fetch_data_process(struct fetch_data_context *c)
{
	fetch_msg msg;
	char *params;
	char *comma;
	char *unescaped;
        int unescaped_len;
	
	/* format of a data: URL is:
	 *   data:[<mimetype>][;base64],<data>
	 * The mimetype is optional.  If it is missing, the , before the
	 * data must still be there.
	 */
	
	LOG("url: %.140s", c->url);
	
	if (strlen(c->url) < 6) {
		/* 6 is the minimum possible length (data:,) */
		msg.type = FETCH_ERROR;
		msg.data.error = "Malformed data: URL";
		fetch_data_send_callback(&msg, c);
		return false;
	}
	
	/* skip the data: part */
	params = c->url + SLEN("data:");
	
	/* find the comma */
	if ( (comma = strchr(params, ',')) == NULL) {
		msg.type = FETCH_ERROR;
		msg.data.error = "Malformed data: URL";
		fetch_data_send_callback(&msg, c);
		return false;
	}
	
	if (params[0] == ',') {
		/* there is no mimetype here, assume text/plain */
		c->mimetype = strdup("text/plain;charset=US-ASCII");
	} else {	
		/* make a copy of everything between data: and the comma */
		c->mimetype = strndup(params, comma - params);
	}
	
	if (c->mimetype == NULL) {
		msg.type = FETCH_ERROR;
		msg.data.error = 
			"Unable to allocate memory for mimetype in data: URL";
		fetch_data_send_callback(&msg, c);
		return false;
	}
	
	if (strcmp(c->mimetype + strlen(c->mimetype) - 7, ";base64") == 0) {
		c->base64 = true;
		c->mimetype[strlen(c->mimetype) - 7] = '\0';
	} else {
		c->base64 = false;
	}
	
	/* URL unescape the data first, just incase some insane page
	 * decides to nest URL and base64 encoding.  Like, say, Acid2.
	 */
        unescaped = curl_easy_unescape(curl, comma + 1, 0, &unescaped_len);
        if (unescaped == NULL) {
		msg.type = FETCH_ERROR;
		msg.data.error = "Unable to URL decode data: URL";
		fetch_data_send_callback(&msg, c);
		return false;
	}
	
	if (c->base64) {
		base64_decode_alloc(unescaped, unescaped_len, &c->data,	&c->datalen);
		if (c->data == NULL) {
			msg.type = FETCH_ERROR;
			msg.data.error = "Unable to Base64 decode data: URL";
			fetch_data_send_callback(&msg, c);
			curl_free(unescaped);
			return false;
		}
	} else {
		c->data = malloc(unescaped_len);
		if (c->data == NULL) {
			msg.type = FETCH_ERROR;
			msg.data.error =
				"Unable to allocate memory for data: URL";
			fetch_data_send_callback(&msg, c);
			curl_free(unescaped);
			return false;
		}
		c->datalen = unescaped_len;
		memcpy(c->data, unescaped, unescaped_len);
	}
	
	curl_free(unescaped);
	
	return true;
}
Exemple #10
0
int main(int argc, char *argv[])
{
	plan(52);

	int32_t  ret;
	uint8_t  in[BUF_LEN], ref[BUF_LEN], out[BUF_LEN], out2[BUF_LEN], *out3;
	uint32_t in_len, ref_len;

	// 0. test invalid input
	ret = base64_encode(NULL, 0, out, BUF_LEN);
	ok(ret == KNOT_EINVAL, "base64_encode: NULL input buffer");
	ret = base64_encode(in, BUF_LEN, NULL, 0);
	ok(ret == KNOT_EINVAL, "base64_encode: NULL output buffer");
	ret = base64_encode(in, MAX_BIN_DATA_LEN + 1, out, BUF_LEN);
	ok(ret == KNOT_ERANGE, "base64_encode: input buffer too large");
	ret = base64_encode(in, BUF_LEN, out, BUF_LEN);
	ok(ret == KNOT_ERANGE, "base64_encode: output buffer too small");

	ret = base64_encode_alloc(NULL, 0, &out3);
	ok(ret == KNOT_EINVAL, "base64_encode_alloc: NULL input buffer");
	ret = base64_encode_alloc(in, MAX_BIN_DATA_LEN + 1, &out3);
	ok(ret == KNOT_ERANGE, "base64_encode_alloc: input buffer too large");
	ret = base64_encode_alloc(in, BUF_LEN, NULL);
	ok(ret == KNOT_EINVAL, "base64_encode_alloc: NULL output buffer");

	ret = base64_decode(NULL, 0, out, BUF_LEN);
	ok(ret == KNOT_EINVAL, "base64_decode: NULL input buffer");
	ret = base64_decode(in, BUF_LEN, NULL, 0);
	ok(ret == KNOT_EINVAL, "base64_decode: NULL output buffer");
	ret = base64_decode(in, UINT32_MAX, out, BUF_LEN);
	ok(ret == KNOT_ERANGE, "base64_decode: input buffer too large");
	ret = base64_decode(in, BUF_LEN, out, 0);
	ok(ret == KNOT_ERANGE, "base64_decode: output buffer too small");

	ret = base64_decode_alloc(NULL, 0, &out3);
	ok(ret == KNOT_EINVAL, "base64_decode_alloc: NULL input buffer");
	ret = base64_decode_alloc(in, UINT32_MAX, &out3);
	ok(ret == KNOT_ERANGE, "base64_decode_aloc: input buffer too large");
	ret = base64_decode_alloc(in, BUF_LEN, NULL);
	ok(ret == KNOT_EINVAL, "base64_decode_alloc: NULL output buffer");

	// 1. test vector -> ENC -> DEC
	strlcpy((char *)in, "", BUF_LEN);
	in_len = strlen((char *)in);
	strlcpy((char *)ref, "", BUF_LEN);
	ref_len = strlen((char *)ref);
	ret = base64_encode(in, in_len, out, BUF_LEN);
	ok(ret == ref_len, "1. test vector - ENC output length");
	if (ret < 0) {
		skip("Encode err");
	} else {
		ok(memcmp(out, ref, ret) == 0, "1. test vector - ENC output content");
	}
	ret = base64_decode(out, ret, out2, BUF_LEN);
	ok(ret == in_len, "1. test vector - DEC output length");
	if (ret < 0) {
		skip("Decode err");
	} else {
		ok(memcmp(out2, in, ret) == 0, "1. test vector - DEC output content");
	}

	// 2. test vector -> ENC -> DEC
	strlcpy((char *)in, "f", BUF_LEN);
	in_len = strlen((char *)in);
	strlcpy((char *)ref, "Zg==", BUF_LEN);
	ref_len = strlen((char *)ref);
	ret = base64_encode(in, in_len, out, BUF_LEN);
	ok(ret == ref_len, "2. test vector - ENC output length");
	if (ret < 0) {
		skip("Encode err");
	} else {
		ok(memcmp(out, ref, ret) == 0, "2. test vector - ENC output content");
	}
	ret = base64_decode(out, ret, out2, BUF_LEN);
	ok(ret == in_len, "2. test vector - DEC output length");
	if (ret < 0) {
		skip("Decode err");
	} else {
		ok(memcmp(out2, in, ret) == 0, "2. test vector - DEC output content");
	}

	// 3. test vector -> ENC -> DEC
	strlcpy((char *)in, "fo", BUF_LEN);
	in_len = strlen((char *)in);
	strlcpy((char *)ref, "Zm8=", BUF_LEN);
	ref_len = strlen((char *)ref);
	ret = base64_encode(in, in_len, out, BUF_LEN);
	ok(ret == ref_len, "3. test vector - ENC output length");
	if (ret < 0) {
		skip("Encode err");
	} else {
		ok(memcmp(out, ref, ret) == 0, "3. test vector - ENC output content");
	}
	ret = base64_decode(out, ret, out2, BUF_LEN);
	ok(ret == in_len, "3. test vector - DEC output length");
	if (ret < 0) {
		skip("Decode err");
	} else {
		ok(memcmp(out2, in, ret) == 0, "3. test vector - DEC output content");
	}

	// 4. test vector -> ENC -> DEC
	strlcpy((char *)in, "foo", BUF_LEN);
	in_len = strlen((char *)in);
	strlcpy((char *)ref, "Zm9v", BUF_LEN);
	ref_len = strlen((char *)ref);
	ret = base64_encode(in, in_len, out, BUF_LEN);
	ok(ret == ref_len, "4. test vector - ENC output length");
	if (ret < 0) {
		skip("Encode err");
	} else {
		ok(memcmp(out, ref, ret) == 0, "4. test vector - ENC output content");
	}
	ret = base64_decode(out, ret, out2, BUF_LEN);
	ok(ret == in_len, "4. test vector - DEC output length");
	if (ret < 0) {
		skip("Decode err");
	} else {
		ok(memcmp(out2, in, ret) == 0, "4. test vector - DEC output content");
	}

	// 5. test vector -> ENC -> DEC
	strlcpy((char *)in, "foob", BUF_LEN);
	in_len = strlen((char *)in);
	strlcpy((char *)ref, "Zm9vYg==", BUF_LEN);
	ref_len = strlen((char *)ref);
	ret = base64_encode(in, in_len, out, BUF_LEN);
	ok(ret == ref_len, "5. test vector - ENC output length");
	if (ret < 0) {
		skip("Encode err");
	} else {
		ok(memcmp(out, ref, ret) == 0, "5. test vector - ENC output content");
	}
	ret = base64_decode(out, ret, out2, BUF_LEN);
	ok(ret == in_len, "5. test vector - DEC output length");
	if (ret < 0) {
		skip("Decode err");
	} else {
		ok(memcmp(out2, in, ret) == 0, "5. test vector - DEC output content");
	}

	// 6. test vector -> ENC -> DEC
	strlcpy((char *)in, "fooba", BUF_LEN);
	in_len = strlen((char *)in);
	strlcpy((char *)ref, "Zm9vYmE=", BUF_LEN);
	ref_len = strlen((char *)ref);
	ret = base64_encode(in, in_len, out, BUF_LEN);
	ok(ret == ref_len, "6. test vector - ENC output length");
	if (ret < 0) {
		skip("Encode err");
	} else {
		ok(memcmp(out, ref, ret) == 0, "6. test vector - ENC output content");
	}
	ret = base64_decode(out, ret, out2, BUF_LEN);
	ok(ret == in_len, "6. test vector - DEC output length");
	if (ret < 0) {
		skip("Decode err");
	} else {
		ok(memcmp(out2, in, ret) == 0, "6. test vector - DEC output content");
	}

	// 7. test vector -> ENC -> DEC
	strlcpy((char *)in, "foobar", BUF_LEN);
	in_len = strlen((char *)in);
	strlcpy((char *)ref, "Zm9vYmFy", BUF_LEN);
	ref_len = strlen((char *)ref);
	ret = base64_encode(in, in_len, out, BUF_LEN);
	ok(ret == ref_len, "7. test vector - ENC output length");
	if (ret < 0) {
		skip("Encode err");
	} else {
		ok(memcmp(out, ref, ret) == 0, "7. test vector - ENC output content");
	}
	ret = base64_decode(out, ret, out2, BUF_LEN);
	ok(ret == in_len, "7. test vector - DEC output length");
	if (ret < 0) {
		skip("Decode err");
	} else {
		ok(memcmp(out2, in, ret) == 0, "7. test vector - DEC output content");
	}

	// Bad paddings
	ret = base64_decode((uint8_t *)"A===", 4, out, BUF_LEN);
	ok(ret == KNOT_BASE64_ECHAR, "Bad padding length 3");
	ret = base64_decode((uint8_t *)"====", 4, out, BUF_LEN);
	ok(ret == KNOT_BASE64_ECHAR, "Bad padding length 4");
	ret = base64_decode((uint8_t *)"AA=A", 4, out, BUF_LEN);
	ok(ret == KNOT_BASE64_ECHAR, "Bad padding character on position 2");
	ret = base64_decode((uint8_t *)"Zg==Zg==", 8, out, BUF_LEN);
	ok(ret == KNOT_BASE64_ECHAR, "Two quartets with padding");

	// Bad data length
	ret = base64_decode((uint8_t *)"A", 1, out, BUF_LEN);
	ok(ret == KNOT_BASE64_ESIZE, "Bad data length 1");
	ret = base64_decode((uint8_t *)"AA", 2, out, BUF_LEN);
	ok(ret == KNOT_BASE64_ESIZE, "Bad data length 2");
	ret = base64_decode((uint8_t *)"AAA", 3, out, BUF_LEN);
	ok(ret == KNOT_BASE64_ESIZE, "Bad data length 3");
	ret = base64_decode((uint8_t *)"AAAAA", 5, out, BUF_LEN);
	ok(ret == KNOT_BASE64_ESIZE, "Bad data length 5");

	// Bad data character
	ret = base64_decode((uint8_t *)"AAA$", 4, out, BUF_LEN);
	ok(ret == KNOT_BASE64_ECHAR, "Bad data character dollar");
	ret = base64_decode((uint8_t *)"AAA ", 4, out, BUF_LEN);
	ok(ret == KNOT_BASE64_ECHAR, "Bad data character space");

	return 0;
}