Ejemplo n.º 1
0
static u2fs_rc parse_registrationData(const char *registrationData,
                                      unsigned char **user_public_key,
                                      size_t * keyHandle_len,
                                      char **keyHandle,
                                      u2fs_X509_t **
                                      attestation_certificate,
                                      u2fs_ECDSA_t ** signature)
{
  base64_decodestate b64;
  size_t registrationData_len = strlen(registrationData);
  unsigned char *data;
  int data_len;
  u2fs_rc rc;

  data = malloc(registrationData_len + 1);
  if (data == NULL)
    return U2FS_MEMORY_ERROR;

  data[registrationData_len] = '\0';

  base64_init_decodestate(&b64);
  data_len =
      base64_decode_block(registrationData, registrationData_len,
                          (char *) data, &b64);

  if (debug) {
    fprintf(stderr, "registrationData Hex: ");
    dumpHex((unsigned char *) data, 0, data_len);
  }

  rc = parse_registrationData2(data, data_len,
                               user_public_key, keyHandle_len, keyHandle,
                               attestation_certificate, signature);

  free(data);
  data = NULL;

  return rc;
}
Ejemplo n.º 2
0
char* decode(const char* input) {
	/* set up a destination buffer large enough to hold the encoded data */
	char* output = (char*) malloc(SIZE);
	/* keep track of our decoded position */
	char* c = output;
	/* store the number of bytes decoded by a single call */
	int cnt = 0;
	/* we need a decoder state */
	base64_decodestate s;

	/*---------- START DECODING ----------*/
	/* initialise the decoder state */
	base64_init_decodestate(&s);
	/* decode the input data */
	cnt = base64_decode_block(input, strlen(input), c, &s);
	c += cnt;
	/* note: there is no base64_decode_blockend! */
	/*---------- STOP DECODING  ----------*/

	/* we want to print the decoded data, so null-terminate it: */
	*c = 0;

	return output;
}
Ejemplo n.º 3
0
/**
 * u2fh_authenticate:
 * @devs: a device handle, from u2fh_devs_init() and u2fh_devs_discover().
 * @challenge: string with JSON data containing the challenge.
 * @origin: U2F origin URL.
 * @response: pointer to output string with JSON data.
 * @flags: set of ORed #u2fh_cmdflags values.
 *
 * Perform the U2F Authenticate operation.
 *
 * Returns: On success %U2FH_OK (integer 0) is returned, and on errors
 * an #u2fh_rc error code.
 */
u2fh_rc
u2fh_authenticate (u2fh_devs * devs,
		   const char *challenge,
		   const char *origin, char **response, u2fh_cmdflags flags)
{
  unsigned char data[CHALLBINLEN + HOSIZE + MAXKHLEN + 1];
  unsigned char buf[MAXDATASIZE];
  char bd[2048];
  size_t bdlen = sizeof (bd);
  size_t len;
  int rc;
  char chalb64[256];
  size_t challen = sizeof (chalb64);
  char khb64[256];
  size_t kh64len = sizeof (khb64);
  base64_decodestate b64;
  size_t khlen;
  int skip_devices[devs->num_devices];
  int skipped = 0;
  int iterations = 0;

  memset (skip_devices, 0, sizeof (skip_devices));

  rc = get_fixed_json_data (challenge, "challenge", chalb64, &challen);
  if (rc != U2FH_OK)
    return rc;

  rc = prepare_browserdata (chalb64, origin, AUTHENTICATE_TYP, bd, &bdlen);
  if (rc != U2FH_OK)
    return rc;

  sha256_buffer (bd, bdlen, data);

  prepare_origin (challenge, data + CHALLBINLEN);

  /* confusion between key_handle and keyHandle */
  rc = get_fixed_json_data (challenge, "keyHandle", khb64, &kh64len);
  if (rc != U2FH_OK)
    return rc;

  base64_init_decodestate (&b64);
  khlen = base64_decode_block (khb64, kh64len,
			       data + HOSIZE + CHALLBINLEN + 1, &b64);
  data[HOSIZE + CHALLBINLEN] = khlen;

  /* FIXME: Support asynchronous usage, through a new u2fh_cmdflags
     flag. */

  do
    {
      int i;
      if (iterations++ > 15)
	{
	  return U2FH_TIMEOUT_ERROR;
	}
      for (i = 0; i < devs->num_devices; i++)
	{
	  unsigned char tmp_buf[MAXDATASIZE];
	  if (skip_devices[i] != 0)
	    {
	      continue;
	    }
	  if (!devs->devs[i].is_alive)
	    {
	      skipped++;
	      skip_devices[i] = 1;
	      continue;
	    }
	  len = MAXDATASIZE;
	  rc = send_apdu (devs, i, U2F_AUTHENTICATE, data,
			  HOSIZE + CHALLBINLEN + khlen + 1,
			  flags & U2FH_REQUEST_USER_PRESENCE ? 3 : 7, tmp_buf,
			  &len);
	  if (rc != U2FH_OK)
	    {
	      return rc;
	    }
	  else if (len != 2)
	    {
	      memcpy (buf, tmp_buf, len);
	      break;
	    }
	  else if (memcmp (tmp_buf, NOTSATISFIED, 2) != 0)
	    {
	      skipped++;
	      skip_devices[i] = 2;
	      continue;
	    }
	  memcpy (buf, tmp_buf, len);
	}
      if (len == 2 && memcmp (buf, NOTSATISFIED, 2) == 0)
	{
	  Sleep (1000);
	}
    }
  while ((flags & U2FH_REQUEST_USER_PRESENCE)
	 && len == 2 && memcmp (buf, NOTSATISFIED, 2) == 0);

  if (len == 2 && memcmp (buf, NOTSATISFIED, 2) != 0)
    {
      return U2FH_AUTHENTICATOR_ERROR;
    }
  if (len != 2)
    {
      prepare_response (buf, len - 2, bd, challenge, response);
    }

  return U2FH_OK;
}
Ejemplo n.º 4
0
wdns_res
_wdns_str_to_rdata_ubuf(ubuf *u, const char *str,
			uint16_t rrtype, uint16_t rrclass) {
	wdns_res res;
	const record_descr *descr = NULL;
	size_t u_orig_size = ubuf_size(u);

	if (rrtype < record_descr_len)
		descr = &record_descr_array[rrtype];

	if (rrtype >= record_descr_len ||
	    (descr != NULL && descr->types[0] == rdf_unknown))
	{
		/* generic encoding */

		if (strncmp(str, "\\#", 2)) {
			res = wdns_res_parse_error;
			goto err;
		}
		str += 2;
		if (!isspace(*str)) {
			res = wdns_res_parse_error;
			goto err;
		}
		while (*str && isspace(*str)) {
			str++;
		}

		const char * ptr = str;
		while (*ptr && !isspace(*ptr)) {
			if (!isdigit(*ptr)) {
				res = wdns_res_parse_error;
				goto err;
			}
			ptr++;
		}

		uint16_t rdlen;
		if (sscanf(str, "%hu", &rdlen) == 0) {
			res = wdns_res_parse_error;
			goto err;
		}
		str = ptr;

		size_t len = 0;
		while (*str) {
			uint8_t c;

			if (isspace(*str)) {
				str++;
				continue;
			}

			if (*(str+1) == 0) {
				res = wdns_res_parse_error;
				goto err;
			}
			if (!sscanf(str, "%02hhx", &c)) {
				res = wdns_res_parse_error;
				goto err;
			}
			ubuf_append(u, &c, 1);
			len++;
			str += 2;
		}
		if (len != rdlen) {
			res = wdns_res_parse_error;
			goto err;
		}

		return (wdns_res_success);
	} else if (descr != NULL && !(descr->record_class == class_un ||
				      descr->record_class == rrclass))
	{
		return (wdns_res_success);
	}

	for (const uint8_t *t = &descr->types[0]; *t != rdf_end; t++) {
		if (str == NULL) {
			break;
		}

		while (isspace(*str)) {
			str++;
		}

		if (*str == 0) {
			break;
		}

		switch (*t) {
		case rdf_name:
		case rdf_uname: {
			wdns_name_t *name;
			char * s;
			const char *end = strpbrk(str, " \t\r\n");

			if (end != NULL) {
				s = strndup(str, end-str);
			} else {
				s = strdup(str);
			}
			name = calloc(1, sizeof(*name));

			res = wdns_str_to_name(s, name);
			if (res != wdns_res_success) {
				free(s);
				free(name);
				goto err;
			}

			ubuf_append(u, name->data, name->len);
			str = end;

			free(s);
			if(name->data) {
				free (name->data);
			}
			free(name);

			break;
		}

		case rdf_bytes:
			while (*str) {
				uint8_t c;
				if (*(str+1) == 0) {
					res = wdns_res_parse_error;
					goto err;
				}
				if (!sscanf(str, "%02hhx", &c)) {
					res = wdns_res_parse_error;
					goto err;
				}
				ubuf_append(u, &c, 1);
				str += 2;
			}
			break;

		case rdf_bytes_b64: {
			base64_decodestate b64;
			char *buf;
			size_t str_len = strlen(str);
			size_t buf_len;

			base64_init_decodestate(&b64);
			buf = malloc(str_len+1);
			buf_len = base64_decode_block((const char *) str, str_len, buf, &b64);
			ubuf_append(u, (uint8_t *) buf, buf_len);
			free(buf);
			str += str_len;
			break;
		}

		case rdf_bytes_str: {
			size_t str_len = strlen(str);

			if (str_len >= 3 && str[0] == '"' && str[str_len - 1] == '"') {
				if (rdata_from_str_string((const uint8_t *)str, u) == 0) {
					res = wdns_res_parse_error;
					goto err;
				}
				str += str_len;
			} else {
				res = wdns_res_parse_error;
				goto err;
			}
			break;
		}

		case rdf_ipv6prefix: {
			uint8_t prefix_len;
			const char *end = strpbrk(str, " \t\r\n");
			const char *ptr = str;

			if (end == NULL) {
				end = str + strlen(str);
			}

			while (ptr < end) {
				if (!isdigit(*ptr++)) {
					res = wdns_res_parse_error;
					goto err;
				}
			}

			if (sscanf(str, "%hhu", &prefix_len) == 0) {
				res = wdns_res_parse_error;
				goto err;
			}

			if (prefix_len > 128) {
				res = wdns_res_parse_error;
				goto err;
			}

			ubuf_append(u, &prefix_len, sizeof(prefix_len));

			str = end;
			if (str) {
				while (isspace(*str)) {
					str++;
				}
			}

			if (prefix_len > 0) {
				if (str == NULL || *str == 0) {
					res = wdns_res_parse_error;
					goto err;
				}

				end = strpbrk(str, " \t\r\n");

				uint8_t oclen = prefix_len / 8;
				if (prefix_len % 8 > 0) {
					oclen++;
				}

				uint8_t addr[16];
				char * pres;

				if (end != NULL) {
					pres = strndup(str, end-str);
				} else {
					pres = strdup(str);
				}

				int pton_res = inet_pton(AF_INET6, pres, addr);
				free(pres);

				if (pton_res == 1) {
					ubuf_append(u, addr, oclen);
				} else {
					res = wdns_res_parse_error;
					goto err;
				}

				str = end;
			}

			break;
		}

		case rdf_salt: {
			const char *end = strpbrk(str, " \t\r\n");
			if (end == NULL) {
				end = str + strlen(str);
			}

			if (*str == '-' && (end-str) == 1) {
				uint8_t c = 0;
				ubuf_append(u, &c, 1);
				str++;
			} else {
				if (end-str > (2*UINT8_MAX) || (end-str) % 2 == 1) {
					res = wdns_res_parse_error;
					goto err;
				}
				uint8_t oclen = (uint8_t)(end-str)/2;
				ubuf_append(u, &oclen, 1);

				while (oclen > 0) {
					uint8_t c;
					if (!sscanf(str, "%02hhx", &c)) {
						res = wdns_res_parse_error;
						goto err;
					}
					ubuf_append(u, &c, 1);
					str += 2;
					oclen--;
				}
			}
			break;
		}

		case rdf_hash: {
			char *buf;
			size_t buf_len;
			const char *end = strpbrk(str, " \t\r\n");

			if (end == NULL) {
				end = str + strlen(str);
			}

			size_t str_len = end-str;
			buf = malloc(str_len);
			buf_len = base32_decode(buf, str_len, str, str_len);

			uint8_t oclen = (uint8_t)buf_len;
			if (oclen != buf_len) {
				free(buf);
				res = wdns_res_parse_error;
				goto err;
			}
			ubuf_append(u, &oclen, 1);
			ubuf_append(u, (uint8_t *) buf, oclen);
			free(buf);
			str = end;
			break;
		}

		case rdf_int8: {
			uint64_t s_val;
			uint8_t val;
			const char *ptr = str;
			const char *end = strpbrk(str, " \t\r\n");

			if (end == NULL) {
				end = str + strlen(str);
			}

			while (ptr < end) {
				if (!isdigit(*ptr++)) {
					res = wdns_res_parse_error;
					goto err;
				}
			}

			if (sscanf(str, "%" PRIu64, &s_val)) {
				val = (uint8_t)s_val;
				if (val != s_val) {
					res = wdns_res_parse_error;
					goto err;
				}
				ubuf_append(u, &val, sizeof(val));
			}
			str = end;
			break;
		}

		case rdf_int16: {
			uint64_t s_val;
			uint16_t val;
			const char *ptr = str;
			const char *end = strpbrk(str, " \t\r\n");

			if (end == NULL) {
				end = str + strlen(str);
			}

			while (ptr < end) {
				if (!isdigit(*ptr++)) {
					res = wdns_res_parse_error;
					goto err;
				}
			}

			if (sscanf(str, "%" PRIu64, &s_val)) {
				val = (uint16_t)s_val;
				if (val != s_val) {
					res = wdns_res_parse_error;
					goto err;
				}
				val = htons(val);
				ubuf_append(u, (uint8_t*)&val, sizeof(val));
			}
			str = end;
			break;
		}

		case rdf_int32: {
			uint64_t s_val;
			uint32_t val;
			const char *ptr = str;
			const char *end = strpbrk(str, " \t\r\n");

			if (end == NULL) {
				end = str + strlen(str);
			}

			while (ptr < end) {
				if (!isdigit(*ptr++)) {
					res = wdns_res_parse_error;
					goto err;
				}
			}

			if (sscanf(str, "%" PRIu64, &s_val)) {
				val = (uint32_t)s_val;
				if (val != s_val) {
					res = wdns_res_parse_error;
					goto err;
				}
				val = htonl(val);
				ubuf_append(u, (uint8_t*)&val, sizeof(val));
			}
			str = end;
			break;
		}

		case rdf_ipv4: {
			uint8_t addr[4];
			char * pres;
			int pton_res;
			const char *end = strpbrk(str, " \t\r\n");

			if (end == NULL) {
				end = str + strlen(str);
			}

			pres = strdup(str);
			pres[end-str] = 0;
			pton_res = inet_pton(AF_INET, pres, addr);
			free(pres);

			if (pton_res == 1) {
				ubuf_append(u, addr, sizeof(addr));
			} else {
				res = wdns_res_parse_error;
				goto err;
			}

			str = end;
			break;
		}

		case rdf_ipv6: {
			uint8_t addr[16];
			char * pres;
			int pton_res;
			const char *end = strpbrk(str, " \t\r\n");

			if (end != NULL) {
				pres = strndup(str, end-str);
			} else {
				pres = strdup(str);
			}
			pton_res = inet_pton(AF_INET6, pres, addr);
			free(pres);

			if (pton_res == 1) {
				ubuf_append(u, addr, sizeof(addr));
			} else {
				res = wdns_res_parse_error;
				goto err;
			}

			str = end;
			break;
		}

		case rdf_eui48: {
			uint8_t a[6] = {0};
			int ret;

			if (strlen(str) != strlen("01-02-03-04-05-06")) {
				res = wdns_res_parse_error;
				goto err;
			}
			for (int i = 0; i < 6; i++) {
				if (!isxdigit(str[3*i]) ||
				    !isxdigit(str[3*i + 1]) ||
				    (i < 5 && str[3*i + 2] != '-'))
				{
					res = wdns_res_parse_error;
					goto err;
				}
			}
			ret = sscanf(str, "%02hhx-%02hhx-%02hhx-%02hhx-%02hhx-%02hhx",
			             &a[0], &a[1], &a[2], &a[3], &a[4], &a[5]);
			if (ret != 6) {
				res = wdns_res_parse_error;
				goto err;
			}
			ubuf_append(u, a, 6);
			str += strlen(str);
			break;
		}

		case rdf_eui64: {
			uint8_t a[8] = {0};
			int ret;

			if (strlen(str) != strlen("01-02-03-04-05-06-07-08")) {
				res = wdns_res_parse_error;
				goto err;
			}
			for (int i = 0; i < 8; i++) {
				if (!isxdigit(str[3*i]) ||
				    !isxdigit(str[3*i + 1]) ||
				    (i < 7 && str[3*i + 2] != '-'))
					{
						res = wdns_res_parse_error;
						goto err;
					}
			}
			ret = sscanf(str, "%02hhx-%02hhx-%02hhx-%02hhx-%02hhx-%02hhx-%02hhx-%02hhx",
			             &a[0], &a[1], &a[2], &a[3], &a[4], &a[5], &a[6], &a[7]);
			if (ret != 8) {
				res = wdns_res_parse_error;
				goto err;
			}
			ubuf_append(u, a, 8);
			str += strlen(str);
			break;
		}

		case rdf_string: {
			const char * end = str;
			size_t u_oclen_offset;
			size_t str_len;
			uint8_t oclen = 0;

			u_oclen_offset = ubuf_size(u);
			ubuf_append(u, &oclen, sizeof(oclen));

			end += rdata_from_str_string((const uint8_t*)str, u);
			if (end == str) {
				res = wdns_res_parse_error;
				goto err;
			}
			str_len = ubuf_size(u) - u_oclen_offset - 1;

			oclen = (uint8_t)str_len;
			if (oclen != str_len) {
				res = wdns_res_parse_error;
				goto err;
			}
			ubuf_data(u)[u_oclen_offset] = oclen;

			str = end;
			break;
		}

		case rdf_repstring: {
			const char * end;
			size_t u_oclen_offset;
			size_t str_len;
			uint8_t oclen = 0;

			while (*str) {
				if (isspace(*str)) {
					str++;
					continue;
				}

				end = str;
				oclen = 0;

				u_oclen_offset = ubuf_size(u);
				ubuf_append(u, &oclen, sizeof(oclen));

				end += rdata_from_str_string((const uint8_t*)str, u);
				if (end == str) {
					res = wdns_res_parse_error;
					goto err;
				}
				str_len = ubuf_size(u) - u_oclen_offset - 1;

				oclen = (uint8_t)str_len;
				if (oclen != str_len) {
					res = wdns_res_parse_error;
					goto err;
				}
				ubuf_data(u)[u_oclen_offset] = oclen;

				str = end;
			}

			break;
		}

		case rdf_rrtype: {
			char * s_rrtype;
			uint16_t my_rrtype;
			const char *end = strpbrk(str, " \t\r\n");

			if (end != NULL) {
				s_rrtype = strndup(str, end-str);
			} else {
				s_rrtype = strdup(str);
			}
			my_rrtype = htons(wdns_str_to_rrtype(s_rrtype));
			free(s_rrtype);

			if (my_rrtype > 0) {
				ubuf_append(u, (const uint8_t*)&my_rrtype, sizeof(my_rrtype));
			} else {
				res = wdns_res_parse_error;
				goto err;
			}

			str = end;
			break;
		}

		case rdf_type_bitmap: {
			const char *end;
			char *s_rrtype;
			u16buf *rrtypes;
			uint16_t my_rrtype, last_rrtype;
			size_t n;
			uint8_t window_block, bitmap_len;
			uint8_t bitmap[32];

			rrtypes = u16buf_init(16);
			if (! rrtypes) {
				res = wdns_res_malloc;
				goto err;
			}

			while (str != NULL && *str) {
				if (isspace(*str)) {
					str++;
					continue;
				}

				end = strpbrk(str, " \t\r\n");
				if (end != NULL) {
					s_rrtype = strndup(str, end-str);
				} else {
					s_rrtype = strdup(str);
				}

				my_rrtype = wdns_str_to_rrtype(s_rrtype);
				free(s_rrtype);

				if (my_rrtype == 0 || (rrtype >= 128 && rrtype < 256) || rrtype == 65535) {
					u16buf_destroy(&rrtypes);
					res = wdns_res_parse_error;
					goto err;
				}

				u16buf_add(rrtypes, my_rrtype);
				str = end;
			}
			qsort(u16buf_ptr(rrtypes), u16buf_size(rrtypes), sizeof(uint16_t), cmp_u16);

			memset(bitmap, 0, sizeof(bitmap));
			window_block = 0;
			bitmap_len = 0;
			last_rrtype = 0;

			for (n = 0; n < u16buf_size(rrtypes); n++) {
				my_rrtype = u16buf_value(rrtypes, n);
				if (my_rrtype == last_rrtype) {
					continue;
				}
				last_rrtype = my_rrtype;

				uint8_t cur_window = my_rrtype / 256;

				if (cur_window != window_block) {
					ubuf_append(u, (const uint8_t*)&window_block, sizeof(window_block));
					ubuf_append(u, (const uint8_t*)&bitmap_len, sizeof(bitmap_len));
					ubuf_append(u, (const uint8_t*)bitmap, bitmap_len);
					memset(bitmap, 0, sizeof(bitmap));
					window_block = cur_window;
				}

				uint8_t offset = my_rrtype % 256;
				uint8_t byte = offset / 8;
				uint8_t bit = offset % 8;

				bitmap[byte] |= 0x80 >> bit;
				bitmap_len = 1 + byte;
			}
			ubuf_append(u, (const uint8_t*)&window_block, sizeof(window_block));
			ubuf_append(u, (const uint8_t*)&bitmap_len, sizeof(bitmap_len));
			ubuf_append(u, (const uint8_t*)bitmap, bitmap_len);

			u16buf_destroy(&rrtypes);
			break;
		}
		default: {
			res = wdns_res_failure;
			goto err;
		}
		} /* switch */
	}

	return wdns_res_success;

err:
	ubuf_clip(u, u_orig_size);
	return res;
}
Ejemplo n.º 5
0
int decode_armor(const uint8_t *armor_in, uint32_t armor_len, uint8_t **plain_out,
                 uint32_t *plain_len)
{
    int ret = -EINVAL;
    const uint8_t *armor_start, *crc_start;
    uint8_t *pgp_plain, *pgp_realloced;
    uint32_t actual_crc24, expected_crc24, crc_plain;
    uint32_t i, encoded_armor_len, plain_armor_len;
    base64_decodestate state;

    /* (6.2) ASCII armor shall be the concatenation of the following data:
      - armor header line
      - armor headers
      - a blank (zero-length, newline only) line
      - the ascii armored data
      - the armor checksum
      - the armor tail */

    /* find the start of the armor */
    i = 1;
    while(i++ < armor_len-1) {
        /* test for both unix style endings and windows style */
        if(armor_in[i-1] == '\n' && armor_in[i] == '\n')
            break;
        else if(i >= 3) {
            if((armor_in[i-3] == '\r' && armor_in[i-2] == '\n' &&
                armor_in[i-1] == '\r' && armor_in[i] == '\n'))
                break;
        }
    }
    /* did we find it? */
    if(i == armor_len)
        goto exit;

    armor_start = armor_in + i;

    /* find the armor checksum and encrypted packet length */
    i = armor_len;
    while(--i) {
        if(armor_in[i] == '=')
            break;
    }
    /* did we find it? */
    if(!i)
        goto exit;

    crc_start = armor_in + i;
    encoded_armor_len = crc_start - armor_start;

    /* do we have enough data for the CRC too?
       CRC is 5 characters long ('=' and CRC) - 3 octets - 24 bits */
    if(encoded_armor_len + 5 > armor_len)
        goto exit;

    /* allocate buffers for plaintext (this is slightly bigger
       than strictly necessary, but will be realloc'ed) */
    pgp_plain = malloc(encoded_armor_len);
    if(!pgp_plain) {
        ret = -ENOMEM;
        goto exit;
    }

    /* decode the data */
    base64_init_decodestate(&state);
    plain_armor_len = base64_decode_block((char*)armor_start, encoded_armor_len, (char*)pgp_plain, &state);

    /* give back the memory we don't need, note that realloc is not responsible for cleaning up
       the original malloc'ed memory if it fails, so we need to keep the original pointer for cleaning
       purposes in case realloc fails (by returning NULL). */
    pgp_realloced = realloc(pgp_plain, plain_armor_len);
    if(!pgp_realloced)
        goto free_pgp;

    pgp_plain = pgp_realloced;

    actual_crc24 = pgp_crc24(plain_armor_len, pgp_plain);

    /* decode the CRC */
    base64_init_decodestate(&state);
    /* ignore '='... */
    base64_decode_block((char*)crc_start + 1, 4, (char*)&crc_plain, &state);

    expected_crc24 = (crc_plain & 0xff0000) >> 16 |
                       (crc_plain & 0x0000ff) << 16 |
                       (crc_plain & 0x00ff00);

    if(actual_crc24 != expected_crc24)
        goto free_pgp;

    *plain_out = pgp_plain;
    *plain_len = plain_armor_len;

    return 0;

free_pgp:
    free(pgp_plain);
exit:
    return ret;
}
Ejemplo n.º 6
0
void decode(const char* buf, char* out, size_t s)
{
	base64_decodestate state;
	base64_init_decodestate(&state);
	base64_decode_block(buf, s, out, &state);
}