Example #1
0
static
void test_hmac_test_vectors(void)
{
	test_begin("test_hmac_test_vectors");

	buffer_t *pt, *ct, *key, *res;
	pt = buffer_create_dynamic(pool_datastack_create(), 50);
	key = buffer_create_dynamic(pool_datastack_create(), 20);
	ct = buffer_create_dynamic(pool_datastack_create(), 32);
	res = buffer_create_dynamic(pool_datastack_create(), 32);

	hex_to_binary("aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa", key);
	hex_to_binary("dddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddddd", pt);
	hex_to_binary("773ea91e36800e46854db8ebd09181a72959098b3ef8c122d9635514ced565fe", res);

	struct dcrypt_context_hmac *hctx;
	if (!dcrypt_ctx_hmac_create("sha256", &hctx, NULL)) {
		test_assert_failed("dcrypt_ctx_hmac_create", __FILE__, __LINE__-1);
	} else {
		dcrypt_ctx_hmac_set_key(hctx, key->data, key->used);
		test_assert(dcrypt_ctx_hmac_init(hctx, NULL));
		test_assert(dcrypt_ctx_hmac_update(hctx, pt->data, pt->used, NULL));
		test_assert(dcrypt_ctx_hmac_final(hctx, ct, NULL));
		test_assert(buffer_cmp(ct, res));
		dcrypt_ctx_hmac_destroy(&hctx);
	}

	test_end();
}
Example #2
0
/*
 * convert the key to a bit pattern
 *	obuf		bit pattern
 *	inbuf		the key itself
 */
void
expand_des_key(char *obuf, char *inbuf)
{
	int i, j;		/* counter in a for loop */
	int nbuf[64];			/* used for hex/key translation */

	/*
	 * leading '0x' or '0X' == hex key
	 */
	if (inbuf[0] == '0' && (inbuf[1] == 'x' || inbuf[1] == 'X')) {
		inbuf = &inbuf[2];
		/*
		 * now translate it, bombing on any illegal hex digit
		 */
		for (i = 0; inbuf[i] && i < 16; i++)
			if ((nbuf[i] = hex_to_binary((int) inbuf[i], 16)) == -1)
				des_error("bad hex digit in key");
		while (i < 16)
			nbuf[i++] = 0;
		for (i = 0; i < 8; i++)
			obuf[i] =
			    ((nbuf[2*i]&0xf)<<4) | (nbuf[2*i+1]&0xf);
		/* preserve parity bits */
		pflag = 1;
		return;
	}
	/*
	 * leading '0b' or '0B' == binary key
	 */
	if (inbuf[0] == '0' && (inbuf[1] == 'b' || inbuf[1] == 'B')) {
		inbuf = &inbuf[2];
		/*
		 * now translate it, bombing on any illegal binary digit
		 */
		for (i = 0; inbuf[i] && i < 16; i++)
			if ((nbuf[i] = hex_to_binary((int) inbuf[i], 2)) == -1)
				des_error("bad binary digit in key");
		while (i < 64)
			nbuf[i++] = 0;
		for (i = 0; i < 8; i++)
			for (j = 0; j < 8; j++)
				obuf[i] = (obuf[i]<<1)|nbuf[8*i+j];
		/* preserve parity bits */
		pflag = 1;
		return;
	}
	/*
	 * no special leader -- ASCII
	 */
	strncpy(obuf, inbuf, 8);
}
Example #3
0
int
main(int argc, char **argv)
{
	FILE *kfile;
	RSA *rsa = NULL;
	char ndata[257], ddata[257];
	/* respond privatefile challenge */
	if (argc < 3)
	{
		puts("Usage: respond privatefile challenge [passphrase]");
		return 0;
	}

	if (argc == 4)
	{
		/* This is TOTALLY insecure and not recommended, but for
		** interfacing with irc client scripts, it's either this
		** or don't use a passphrase.
		**
		** The likelihood of a passphrase leaking isn't TOO great,
		** only ps auxww will show it, and even then, only at the
		** precise moment this is called.
		*/
		insecure_mode = 1;
		pass_param = argv[3];
	}

	if (!(kfile = fopen(argv[1], "r")))
	{
		puts("Could not open the private keyfile.");
		return 0;
	}
	
	SSLeay_add_all_ciphers();
	rsa = PEM_read_RSAPrivateKey(kfile, NULL,pass_cb, NULL);
  
	if(!rsa)
	{
		puts("Unable to read your private key, is the passphrase wrong?");
		return 0;
	}

	 fclose(kfile);
	if (hex_to_binary(argv[2], ndata, 128) != 128)
	{
		puts("Bad challenge.");
		return -1;
	}

	if (RSA_private_decrypt(128, (unsigned char*)ndata,
		(unsigned char*)ddata, rsa, RSA_PKCS1_PADDING) == -1)
	{
		puts("Decryption error.");
		return -1;
	}
	binary_to_hex((unsigned char*)ddata, ndata, 32);
	puts(ndata);
	return 0;
}
Example #4
0
static void test_hex_to_binary(void)
{
	static const char *ok_input = "0001fEFf";
	static unsigned char ok_output[] = { 0x00, 0x01, 0xfe, 0xff };
	static const char *error_input[] = {
		"00 01",
		"0x01",
		"0g"
	};
	buffer_t *buf = buffer_create_dynamic(pool_datastack_create(), 10);
	unsigned int i;

	test_begin("hex to binary");
	test_assert(hex_to_binary("", buf) == 0);
	test_assert(buf->used == 0);

	test_assert(hex_to_binary(ok_input, buf) == 0);
	test_assert(buf->used == N_ELEMENTS(ok_output));
	test_assert(memcmp(buf->data, ok_output, buf->used) == 0);

	for (i = 0; i < N_ELEMENTS(error_input); i++)
		test_assert(hex_to_binary(error_input[i], buf) == -1);
	test_end();
}
static bool
master_input_request(struct auth_master_connection *conn, const char *args)
{
	struct auth_client_connection *client_conn;
	const char *const *list, *const *params;
	unsigned int id, client_pid, client_id;
	uint8_t cookie[MASTER_AUTH_COOKIE_SIZE];
	buffer_t buf;

	/* <id> <client-pid> <client-id> <cookie> [<parameters>] */
	list = t_strsplit_tab(args);
	if (str_array_length(list) < 4 ||
	    str_to_uint(list[0], &id) < 0 ||
	    str_to_uint(list[1], &client_pid) < 0 ||
	    str_to_uint(list[2], &client_id) < 0) {
		i_error("BUG: Master sent broken REQUEST");
		return FALSE;
	}

	buffer_create_from_data(&buf, cookie, sizeof(cookie));
	if (hex_to_binary(list[3], &buf) < 0) {
		i_error("BUG: Master sent broken REQUEST cookie");
		return FALSE;
	}
	params = list + 4;

	client_conn = auth_client_connection_lookup(client_pid);
	if (client_conn == NULL) {
		i_error("Master requested auth for nonexistent client %u",
			client_pid);
		o_stream_nsend_str(conn->output,
				   t_strdup_printf("FAIL\t%u\n", id));
	} else if (memcmp(client_conn->cookie, cookie, sizeof(cookie)) != 0) {
		i_error("Master requested auth for client %u with invalid cookie",
			client_pid);
		o_stream_nsend_str(conn->output,
				   t_strdup_printf("FAIL\t%u\n", id));
	} else if (!auth_request_handler_master_request(
			client_conn->request_handler, conn, id, client_id, params)) {
		i_error("Master requested auth for non-login client %u",
			client_pid);
		o_stream_nsend_str(conn->output,
				   t_strdup_printf("FAIL\t%u\n", id));
	}
	return TRUE;
}
Example #6
0
int quoted_printable_q_decode(const unsigned char *src, size_t src_size,
			      buffer_t *dest)
{
	char hexbuf[3];
	size_t src_pos, next;
	bool errors = FALSE;

	hexbuf[2] = '\0';

	next = 0;
	for (src_pos = 0; src_pos < src_size; src_pos++) {
		if (src[src_pos] != '_' && src[src_pos] != '=')
			continue;

		buffer_append(dest, src + next, src_pos - next);
		next = src_pos;

		if (src[src_pos] == '_') {
			buffer_append_c(dest, ' ');
			next++;
			continue;
		}

		if (src_pos+2 >= src_size)
			break;

		/* =<hex> */
		hexbuf[0] = src[src_pos+1];
		hexbuf[1] = src[src_pos+2];

		if (hex_to_binary(hexbuf, dest) == 0) {
			src_pos += 2;
			next = src_pos+1;
		} else {
			/* non-hex data, show as-is */
			errors = TRUE;
			next = src_pos;
		}
	}
	buffer_append(dest, src + next, src_size - next);
	return errors ? -1 : 0;
}
Example #7
0
static int
quoted_printable_decode_full(const unsigned char *src, size_t src_size,
			     size_t *src_pos_r, buffer_t *dest, bool eof)
{
	char hexbuf[3];
	size_t src_pos, pos, next;
	bool errors = FALSE;
	int ret;

	hexbuf[2] = '\0';

	next = 0;
	for (src_pos = 0; src_pos < src_size; src_pos++) {
		if (src[src_pos] != '=' && src[src_pos] != '\n')
			continue;

		if (src[src_pos] == '\n') {
			/* drop trailing whitespace */
			pos = src_pos;
			if (pos > 0 && src[pos-1] == '\r')
				pos--;
			while (pos > 0 && QP_IS_TRAILING_SPACE(src[pos-1]))
				pos--;
			buffer_append(dest, src + next, pos - next);
			next = src_pos+1;
			buffer_append_c(dest, '\r');
			buffer_append_c(dest, '\n');
			continue;
		}

		/* '=' */
		buffer_append(dest, src + next, src_pos - next);
		next = src_pos;

		if ((ret = qp_is_end_of_line(src, &src_pos, src_size)) > 0) {
			/* =[whitespace][\r]\n */
			next = src_pos+1;
			continue;
		}
		if (ret < 0) {
			/* '=' was followed only by whitespace */
			break;
		}
		if (src_pos+2 >= src_size) {
			/* '=' was followed by non-whitespace */
			if (eof)
				errors = TRUE;
			break;
		}

		/* =<hex> */
		hexbuf[0] = src[src_pos+1];
		hexbuf[1] = src[src_pos+2];

		if (hex_to_binary(hexbuf, dest) == 0) {
			src_pos += 2;
			next = src_pos + 1;
		} else {
			/* non-hex data, show as-is */
			errors = TRUE;
			next = src_pos;
		}
	}
	if (src_pos == src_size) {
		/* add everything but trailing spaces */
		if (src_pos > 0 && src[src_pos-1] == '\r')
			src_pos--;
		while (src_pos > 0 && QP_IS_TRAILING_SPACE(src[src_pos-1]))
			src_pos--;
		buffer_append(dest, src + next, src_pos - next);
		next = src_pos;
	}
	*src_pos_r = next;
	return errors ? -1 : 0;
}
Example #8
0
static
void test_cipher_test_vectors(void)
{
	static struct {
		const char *key;
		const char *iv;
		const char *pt;
		const char *ct;
	} vectors[] =
	{
		{ "2b7e151628aed2a6abf7158809cf4f3c", "000102030405060708090a0b0c0d0e0f", "6bc1bee22e409f96e93d7e117393172a", "7649abac8119b246cee98e9b12e9197d" },
		{ "2b7e151628aed2a6abf7158809cf4f3c", "7649ABAC8119B246CEE98E9B12E9197D", "ae2d8a571e03ac9c9eb76fac45af8e51", "5086cb9b507219ee95db113a917678b2" }
	};


	test_begin("test_cipher_test_vectors");

	buffer_t *key,*iv,*pt,*ct,*res_enc,*res_dec;

	key = buffer_create_dynamic(pool_datastack_create(), 16);
	iv = buffer_create_dynamic(pool_datastack_create(), 16);
	pt = buffer_create_dynamic(pool_datastack_create(), 16);
	ct = buffer_create_dynamic(pool_datastack_create(), 16);

	res_enc = buffer_create_dynamic(pool_datastack_create(), 32);
	res_dec = buffer_create_dynamic(pool_datastack_create(), 32);

	for(size_t i = 0; i < N_ELEMENTS(vectors); i++) {
		struct dcrypt_context_symmetric *ctx;

		buffer_set_used_size(key, 0);
		buffer_set_used_size(iv, 0);
		buffer_set_used_size(pt, 0);
		buffer_set_used_size(ct, 0);
		buffer_set_used_size(res_enc, 0);
		buffer_set_used_size(res_dec, 0);

		hex_to_binary(vectors[i].key, key);
		hex_to_binary(vectors[i].iv, iv);
		hex_to_binary(vectors[i].pt, pt);
		hex_to_binary(vectors[i].ct, ct);

		if (!dcrypt_ctx_sym_create("AES-128-CBC", DCRYPT_MODE_ENCRYPT, &ctx, NULL)) {
			test_assert_failed("dcrypt_ctx_sym_create", __FILE__, __LINE__-1);
			continue;
		}

		dcrypt_ctx_sym_set_padding(ctx, FALSE);

		dcrypt_ctx_sym_set_key(ctx, key->data, key->used);
		dcrypt_ctx_sym_set_iv(ctx, iv->data, iv->used);

		test_assert_idx(dcrypt_ctx_sym_init(ctx, NULL), i);

		test_assert_idx(dcrypt_ctx_sym_update(ctx, pt->data, pt->used, res_enc, NULL), i);
		test_assert_idx(dcrypt_ctx_sym_final(ctx, res_enc, NULL), i);

		test_assert_idx(buffer_cmp(ct, res_enc), i);

		dcrypt_ctx_sym_destroy(&ctx);

		if (!dcrypt_ctx_sym_create("AES-128-CBC", DCRYPT_MODE_DECRYPT, &ctx, NULL)) {
			test_assert_failed("dcrypt_ctx_sym_create", __FILE__, __LINE__-1);
			continue;
		}

		dcrypt_ctx_sym_set_padding(ctx, FALSE);

		dcrypt_ctx_sym_set_key(ctx, key->data, key->used);
		dcrypt_ctx_sym_set_iv(ctx, iv->data, iv->used);

		test_assert_idx(dcrypt_ctx_sym_init(ctx, NULL), i);
		test_assert_idx(dcrypt_ctx_sym_update(ctx, res_enc->data, res_enc->used, res_dec, NULL), i);
		test_assert_idx(dcrypt_ctx_sym_final(ctx, res_dec, NULL), i);

		test_assert_idx(buffer_cmp(pt, res_dec), i);

		dcrypt_ctx_sym_destroy(&ctx);
	}

	test_end();
}
Example #9
0
static
void test_cipher_aead_test_vectors(void)
{
	struct dcrypt_context_symmetric *ctx;
	const char *error = NULL;

	test_begin("test_cipher_aead_test_vectors");

	if (!dcrypt_ctx_sym_create("aes-128-gcm", DCRYPT_MODE_ENCRYPT, &ctx, &error)) {
		test_assert_failed("dcrypt_ctx_sym_create", __FILE__, __LINE__-1);
		return;
	}

	buffer_t *key, *iv, *aad, *pt, *ct, *tag, *tag_res, *res;

	key = buffer_create_dynamic(pool_datastack_create(), 16);
	iv = buffer_create_dynamic(pool_datastack_create(), 16);
	aad = buffer_create_dynamic(pool_datastack_create(), 16);
	pt = buffer_create_dynamic(pool_datastack_create(), 16);
	ct = buffer_create_dynamic(pool_datastack_create(), 16);
	tag = buffer_create_dynamic(pool_datastack_create(), 16);
	res = buffer_create_dynamic(pool_datastack_create(), 16);
	tag_res = buffer_create_dynamic(pool_datastack_create(), 16);

	hex_to_binary("feffe9928665731c6d6a8f9467308308", key);
	hex_to_binary("cafebabefacedbaddecaf888", iv);
	hex_to_binary("d9313225f88406e5a55909c5aff5269a86a7a9531534f7da2e4c303d8a318a721c3c0c95956809532fcf0e2449a6b525b16aedf5aa0de657ba637b391aafd255", pt);
	hex_to_binary("42831ec2217774244b7221b784d0d49ce3aa212f2c02a4e035c17e2329aca12e21d514b25466931c7d8f6a5aac84aa051ba30b396a0aac973d58e091473f5985", ct);
	hex_to_binary("4d5c2af327cd64a62cf35abd2ba6fab4", tag);

	dcrypt_ctx_sym_set_key(ctx, key->data, key->used);
	dcrypt_ctx_sym_set_iv(ctx, iv->data, iv->used);
	dcrypt_ctx_sym_set_aad(ctx, aad->data, aad->used);
	test_assert(dcrypt_ctx_sym_init(ctx, &error));
	test_assert(dcrypt_ctx_sym_update(ctx, pt->data, pt->used, res, &error));
	test_assert(dcrypt_ctx_sym_final(ctx, res, &error));
	test_assert(dcrypt_ctx_sym_get_tag(ctx, tag_res));

	test_assert(buffer_cmp(ct, res) == TRUE);
	test_assert(buffer_cmp(tag, tag_res) == TRUE);

	dcrypt_ctx_sym_destroy(&ctx);

	if (!dcrypt_ctx_sym_create("aes-128-gcm", DCRYPT_MODE_DECRYPT, &ctx, &error)) {
		test_assert_failed("dcrypt_ctx_sym_create", __FILE__, __LINE__-1);
	} else {

		buffer_set_used_size(res, 0);

		dcrypt_ctx_sym_set_key(ctx, key->data, key->used);
		dcrypt_ctx_sym_set_iv(ctx, iv->data, iv->used);
		dcrypt_ctx_sym_set_aad(ctx, aad->data, aad->used);
		dcrypt_ctx_sym_set_tag(ctx, tag->data, tag->used);
		test_assert(dcrypt_ctx_sym_init(ctx, &error));
		test_assert(dcrypt_ctx_sym_update(ctx, ct->data, ct->used, res, &error));
		test_assert(dcrypt_ctx_sym_final(ctx, res, &error));

		test_assert(buffer_cmp(pt, res) == TRUE);

		dcrypt_ctx_sym_destroy(&ctx);
	}

	test_end();
}
Example #10
0
int main(int argc, char *argv[])
{
	char *pass = NULL;
	unsigned char *salt;
	int salt_len;                  // salt length in bytes
	int ic=0;                        // iterative count
	int result_len;
	unsigned char *result;       // result (binary - 32+16 chars)
	int i;

	if ( argc != 4 ) {
		fprintf(stderr, "usage: %s salt count len <passwd >binary_key_iv\n", argv[0]);
		exit(10);
	}

	//TODO: move to base64decode
	salt=calloc(strlen(argv[1])/2+3, sizeof(char));
	salt_len=hex_to_binary(salt, argv[1]);
	if( salt_len <= 0 ) {
		fprintf(stderr, "Error: %s is not a valid salt (it must be a hexadecimal string)\n", argv[1]);
		exit(1);
	}

	if( sscanf(argv[2], "%d", &ic) == 0 || ic<=0) {
		fprintf(stderr, "Error: count must be a positive integer\n");
		exit(1);
	}
	if( sscanf(argv[3], "%d", &result_len) == 0 || result_len<=0) {
		fprintf(stderr, "Error: result_len must be a positive integer\n");
		exit(1);
	}

	fscanf(stdin, "%ms", &pass);
	if ( pass[strlen(pass)-1] == '\n' )
		pass[strlen(pass)-1] = '\0';

	// PBKDF 2
	result = calloc(result_len, sizeof(unsigned char*));
	if (!gcry_check_version ("1.5.0")) {
		fputs ("libgcrypt version mismatch\n", stderr);
		exit (2);
	}
	/* Allocate a pool of 16k secure memory.  This make the secure memory
	available and also drops privileges where needed.  */
	gcry_control (GCRYCTL_INIT_SECMEM, 16384, 0);
	/* It is now okay to let Libgcrypt complain when there was/is
	a problem with the secure memory. */
	gcry_control (GCRYCTL_RESUME_SECMEM_WARN);
	/* Tell Libgcrypt that initialization has completed. */
	gcry_control (GCRYCTL_INITIALIZATION_FINISHED, 0);

	gcry_kdf_derive( pass, strlen(pass), GCRY_KDF_PBKDF2, GCRY_MD_SHA1, salt, salt_len, ic, result_len, result);
	print_hex(result, result_len);            // Key + IV   (as hex string)

	//clear and free everything
	for(i=0; i<result_len;i++)
		result[i]=0;
	free(result);
	for(i=0; i<strlen(pass); i++) //blank
		pass[i]=0;
	free(pass);
	for(i=0; i<strlen(argv[1])/2+3; i++) //blank
		salt[i]=0;
	free(salt);

	return(0);
}
Example #11
0
void load_reg_key( regkey_t *parent, xmlNode *node )
{
	xmlAttr *e;
	xmlChar *contents = NULL;
	const char *type = NULL;
	const char *keycls = NULL;
	unicode_string_t name, data;
	xmlNode *n;
	regval_t *val;
	ULONG size;
	regkey_t *key;

	if (!node->name[0] || node->name[1])
		return;

	for ( e = node->properties; e; e = e->next )
	{
		if (!strcmp( (const char*)e->name, "n"))
			contents = xmlNodeGetContent( (xmlNode*) e );
		else if (!strcmp( (const char*)e->name, "t"))
			type = (const char*) xmlNodeGetContent( (xmlNode*) e );
		else if (!strcmp( (const char*)e->name, "c"))
			keycls = (const char*) xmlNodeGetContent( (xmlNode*) e );
	}

	if (!contents)
		return;

	name.copy( contents );

	switch (node->name[0])
	{
	case 'x': // value stored as hex
		// default type is binary
		if (type == NULL)
			type = "3";
		contents = xmlNodeGetContent( node );
		size = hex_to_binary( contents, 0, NULL );
		val = new regval_t( &name, atoi(type), size );
		hex_to_binary( contents, size, val->data );
		parent->values.append( val );
		break;

	case 'n': // number
		// default type is REG_DWORD
		if (type == NULL)
			type = "4";
		contents = xmlNodeGetContent( node );
		size = sizeof (ULONG);
		val = new regval_t( &name, atoi(type), size );
		number_to_binary( contents, size, val->data );
		parent->values.append( val );
		break;

	case 's': // value stored as a string
		// default type is REG_SZ
		if (type == NULL)
			type = "1";

		data.copy( xmlNodeGetContent( node ) );
		val = new regval_t( &name, atoi(type), data.Length + 2 );
		memcpy( val->data, data.Buffer, data.Length );
		memset( val->data + data.Length, 0, 2 );
		parent->values.append( val );
		break;

	case 'k': // key
		key = build_key( parent, &name );
		key->cls.copy( keycls );
		for (n = node->children; n; n = n->next)
			load_reg_key( key, n );

		break;
	}
}
Example #12
0
int password_decode(const char *password, const char *scheme,
		    const unsigned char **raw_password_r, size_t *size_r,
		    const char **error_r)
{
	const struct password_scheme *s;
	enum password_encoding encoding;
	buffer_t *buf;
	size_t len;
	bool guessed_encoding;

	*error_r = NULL;

	s = password_scheme_lookup(scheme, &encoding);
	if (s == NULL) {
		*error_r = "Unknown scheme";
		return 0;
	}

	len = strlen(password);
	if (encoding != PW_ENCODING_NONE && s->raw_password_len != 0 &&
	    strchr(scheme, '.') == NULL) {
		/* encoding not specified. we can guess quite well between
		   base64 and hex encodings. the only problem is distinguishing
		   2 character strings, but there shouldn't be any that short
		   raw_password_lens. */
		encoding = len == s->raw_password_len * 2 ?
			PW_ENCODING_HEX : PW_ENCODING_BASE64;
		guessed_encoding = TRUE;
	} else {
		guessed_encoding = FALSE;
	}

	switch (encoding) {
	case PW_ENCODING_NONE:
		*raw_password_r = (const unsigned char *)password;
		*size_r = len;
		break;
	case PW_ENCODING_HEX:
		buf = t_buffer_create(len / 2 + 1);
		if (hex_to_binary(password, buf) == 0) {
			*raw_password_r = buf->data;
			*size_r = buf->used;
			break;
		}
		if (!guessed_encoding) {
			*error_r = "Input isn't valid HEX encoded data";
			return -1;
		}
		/* check if it's base64-encoded after all. some input lengths
		   produce matching hex and base64 encoded lengths. */
		/* fall through */
	case PW_ENCODING_BASE64:
		buf = t_buffer_create(MAX_BASE64_DECODED_SIZE(len));
		if (base64_decode(password, len, NULL, buf) < 0) {
			*error_r = "Input isn't valid base64 encoded data";
			return -1;
		}

		*raw_password_r = buf->data;
		*size_r = buf->used;
		break;
	}
	if (s->raw_password_len != *size_r && s->raw_password_len != 0) {
		/* password has invalid length */
		*error_r = t_strdup_printf(
			"Input length isn't valid (%u instead of %u)",
			(unsigned int)*size_r, s->raw_password_len);
		return -1;
	}
	return 1;
}
 blob loadsignature (std::string const& hex)
 {
     blob b;
     hex_to_binary (hex.begin (), hex.end (), b);
     return b;
 }