pidgin/pidgin
Clone
Summary
Browse
Changes
Graph
Fix a regression bug in signals-test.c
2015-06-23, Koosha Khajehmoogahi
ef7d5e45fe84
Fix a regression bug in signals-test.c
Signed-off-by: Richard Laager
/* purple
*
* Purple is the legal property of its developers, whose names are too numerous
* to list here. Please refer to the COPYRIGHT file distributed with this
* source distribution.
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU General Public License as published by
* the Free Software Foundation; either version 2 of the License, or
* (at your option) any later version.
*
* This program is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
* GNU General Public License for more details.
*
* You should have received a copy of the GNU General Public License
* along with this program; if not, write to the Free Software
* Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02111-1301 USA
*/
#include
"internal.h"
#include
"cipher.h"
#include
"debug.h"
/******************************************************************************
* PurpleCipher API
*****************************************************************************/
GType
purple_cipher_get_type
(
void
)
{
static
GType
type
=
0
;
if
(
type
==
0
)
{
static
const
GTypeInfo
info
=
{
sizeof
(
PurpleCipherClass
),
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
sizeof
(
PurpleCipher
),
0
,
NULL
,
NULL
};
type
=
g_type_register_static
(
G_TYPE_OBJECT
,
"PurpleCipher"
,
&
info
,
G_TYPE_FLAG_ABSTRACT
);
}
return
type
;
}
static
const
gchar
*
purple_cipher_get_name
(
PurpleCipher
*
cipher
)
{
PurpleCipherClass
*
klass
;
const
gchar
*
name
;
if
(
!
PURPLE_IS_CIPHER
(
cipher
))
return
"(error: not a cipher)"
;
klass
=
PURPLE_CIPHER_GET_CLASS
(
cipher
);
if
(
!
klass
)
return
"(error: unknown cipher class)"
;
name
=
g_type_name
(
G_TYPE_FROM_CLASS
(
klass
));
if
(
!
name
)
return
"(error: unknown cipher name)"
;
return
name
;
}
static
const
gchar
*
purple_hash_get_name
(
PurpleHash
*
hash
)
{
PurpleHashClass
*
klass
;
const
gchar
*
name
;
if
(
!
PURPLE_IS_HASH
(
hash
))
return
"(error: not a hash)"
;
klass
=
PURPLE_HASH_GET_CLASS
(
hash
);
if
(
!
klass
)
return
"(error: unknown hash class)"
;
name
=
g_type_name
(
G_TYPE_FROM_CLASS
(
klass
));
if
(
!
name
)
return
"(error: unknown hash name)"
;
return
name
;
}
void
purple_cipher_reset
(
PurpleCipher
*
cipher
)
{
PurpleCipherClass
*
klass
=
NULL
;
g_return_if_fail
(
PURPLE_IS_CIPHER
(
cipher
));
klass
=
PURPLE_CIPHER_GET_CLASS
(
cipher
);
if
(
klass
&&
klass
->
reset
)
klass
->
reset
(
cipher
);
else
{
purple_debug_warning
(
"cipher"
,
"the %s cipher does not "
"implement the reset method"
,
purple_cipher_get_name
(
cipher
));
}
}
void
purple_cipher_reset_state
(
PurpleCipher
*
cipher
)
{
PurpleCipherClass
*
klass
=
NULL
;
g_return_if_fail
(
PURPLE_IS_CIPHER
(
cipher
));
klass
=
PURPLE_CIPHER_GET_CLASS
(
cipher
);
if
(
klass
&&
klass
->
reset_state
)
klass
->
reset_state
(
cipher
);
else
{
purple_debug_warning
(
"cipher"
,
"the %s cipher does not "
"implement the reset_state method"
,
purple_cipher_get_name
(
cipher
));
}
}
void
purple_cipher_set_iv
(
PurpleCipher
*
cipher
,
guchar
*
iv
,
size_t
len
)
{
PurpleCipherClass
*
klass
=
NULL
;
g_return_if_fail
(
PURPLE_IS_CIPHER
(
cipher
));
g_return_if_fail
(
iv
);
klass
=
PURPLE_CIPHER_GET_CLASS
(
cipher
);
if
(
klass
&&
klass
->
set_iv
)
klass
->
set_iv
(
cipher
,
iv
,
len
);
else
{
purple_debug_warning
(
"cipher"
,
"the %s cipher does not "
"implement the set_iv method"
,
purple_cipher_get_name
(
cipher
));
}
}
void
purple_cipher_append
(
PurpleCipher
*
cipher
,
const
guchar
*
data
,
size_t
len
)
{
PurpleCipherClass
*
klass
=
NULL
;
g_return_if_fail
(
PURPLE_IS_CIPHER
(
cipher
));
klass
=
PURPLE_CIPHER_GET_CLASS
(
cipher
);
if
(
klass
&&
klass
->
append
)
klass
->
append
(
cipher
,
data
,
len
);
else
{
purple_debug_warning
(
"cipher"
,
"the %s cipher does not "
"implement the append method"
,
purple_cipher_get_name
(
cipher
));
}
}
gboolean
purple_cipher_digest
(
PurpleCipher
*
cipher
,
guchar
digest
[],
size_t
len
)
{
PurpleCipherClass
*
klass
=
NULL
;
g_return_val_if_fail
(
PURPLE_IS_CIPHER
(
cipher
),
FALSE
);
klass
=
PURPLE_CIPHER_GET_CLASS
(
cipher
);
if
(
klass
&&
klass
->
digest
)
return
klass
->
digest
(
cipher
,
digest
,
len
);
else
{
purple_debug_warning
(
"cipher"
,
"the %s cipher does not "
"implement the digest method"
,
purple_cipher_get_name
(
cipher
));
}
return
FALSE
;
}
gboolean
purple_cipher_digest_to_str
(
PurpleCipher
*
cipher
,
gchar
digest_s
[],
size_t
len
)
{
/* 8k is a bit excessive, will tweak later. */
guchar
digest
[
BUF_LEN
*
4
];
size_t
digest_size
,
n
;
g_return_val_if_fail
(
PURPLE_IS_CIPHER
(
cipher
),
FALSE
);
g_return_val_if_fail
(
digest_s
,
FALSE
);
digest_size
=
purple_cipher_get_digest_size
(
cipher
);
g_return_val_if_fail
(
digest_size
<=
BUF_LEN
*
4
,
FALSE
);
if
(
!
purple_cipher_digest
(
cipher
,
digest
,
sizeof
(
digest
)))
return
FALSE
;
/* Every digest byte occupies 2 chars + the NUL at the end. */
g_return_val_if_fail
(
digest_size
*
2
+
1
<=
len
,
FALSE
);
for
(
n
=
0
;
n
<
digest_size
;
n
++
)
sprintf
(
digest_s
+
(
n
*
2
),
"%02x"
,
digest
[
n
]);
digest_s
[
n
*
2
]
=
'\0'
;
return
TRUE
;
}
size_t
purple_cipher_get_digest_size
(
PurpleCipher
*
cipher
)
{
PurpleCipherClass
*
klass
=
NULL
;
g_return_val_if_fail
(
PURPLE_IS_CIPHER
(
cipher
),
FALSE
);
klass
=
PURPLE_CIPHER_GET_CLASS
(
cipher
);
if
(
klass
&&
klass
->
get_digest_size
)
return
klass
->
get_digest_size
(
cipher
);
else
{
purple_debug_warning
(
"cipher"
,
"the %s cipher does not "
"implement the get_digest_size method"
,
purple_cipher_get_name
(
cipher
));
}
return
FALSE
;
}
ssize_t
purple_cipher_encrypt
(
PurpleCipher
*
cipher
,
const
guchar
input
[],
size_t
in_len
,
guchar
output
[],
size_t
out_size
)
{
PurpleCipherClass
*
klass
=
NULL
;
g_return_val_if_fail
(
PURPLE_IS_CIPHER
(
cipher
),
-1
);
g_return_val_if_fail
(
input
!=
NULL
,
-1
);
g_return_val_if_fail
(
output
!=
NULL
,
-1
);
g_return_val_if_fail
(
out_size
>=
in_len
,
-1
);
klass
=
PURPLE_CIPHER_GET_CLASS
(
cipher
);
if
(
klass
&&
klass
->
encrypt
)
return
klass
->
encrypt
(
cipher
,
input
,
in_len
,
output
,
out_size
);
else
{
purple_debug_warning
(
"cipher"
,
"the %s cipher does not "
"implement the encrypt method"
,
purple_cipher_get_name
(
cipher
));
}
return
-1
;
}
ssize_t
purple_cipher_decrypt
(
PurpleCipher
*
cipher
,
const
guchar
input
[],
size_t
in_len
,
guchar
output
[],
size_t
out_size
)
{
PurpleCipherClass
*
klass
=
NULL
;
g_return_val_if_fail
(
PURPLE_IS_CIPHER
(
cipher
),
-1
);
g_return_val_if_fail
(
input
!=
NULL
,
-1
);
g_return_val_if_fail
(
output
!=
NULL
,
-1
);
klass
=
PURPLE_CIPHER_GET_CLASS
(
cipher
);
if
(
klass
&&
klass
->
decrypt
)
return
klass
->
decrypt
(
cipher
,
input
,
in_len
,
output
,
out_size
);
else
{
purple_debug_warning
(
"cipher"
,
"the %s cipher does not "
"implement the decrypt method"
,
purple_cipher_get_name
(
cipher
));
}
return
-1
;
}
void
purple_cipher_set_salt
(
PurpleCipher
*
cipher
,
const
guchar
*
salt
,
size_t
len
)
{
PurpleCipherClass
*
klass
=
NULL
;
g_return_if_fail
(
PURPLE_IS_CIPHER
(
cipher
));
klass
=
PURPLE_CIPHER_GET_CLASS
(
cipher
);
if
(
klass
&&
klass
->
set_salt
)
klass
->
set_salt
(
cipher
,
salt
,
len
);
else
{
purple_debug_warning
(
"cipher"
,
"the %s cipher does not "
"implement the set_salt method"
,
purple_cipher_get_name
(
cipher
));
}
}
void
purple_cipher_set_key
(
PurpleCipher
*
cipher
,
const
guchar
*
key
,
size_t
len
)
{
PurpleCipherClass
*
klass
=
NULL
;
g_return_if_fail
(
PURPLE_IS_CIPHER
(
cipher
));
klass
=
PURPLE_CIPHER_GET_CLASS
(
cipher
);
if
(
klass
&&
klass
->
set_key
)
klass
->
set_key
(
cipher
,
key
,
len
);
else
{
purple_debug_warning
(
"cipher"
,
"the %s cipher does not "
"implement the set_key method"
,
purple_cipher_get_name
(
cipher
));
}
}
size_t
purple_cipher_get_key_size
(
PurpleCipher
*
cipher
)
{
PurpleCipherClass
*
klass
=
NULL
;
g_return_val_if_fail
(
PURPLE_IS_CIPHER
(
cipher
),
-1
);
klass
=
PURPLE_CIPHER_GET_CLASS
(
cipher
);
if
(
klass
&&
klass
->
get_key_size
)
return
klass
->
get_key_size
(
cipher
);
else
{
purple_debug_warning
(
"cipher"
,
"the %s cipher does not "
"implement the get_key_size method"
,
purple_cipher_get_name
(
cipher
));
}
return
-1
;
}
void
purple_cipher_set_batch_mode
(
PurpleCipher
*
cipher
,
PurpleCipherBatchMode
mode
)
{
PurpleCipherClass
*
klass
=
NULL
;
g_return_if_fail
(
PURPLE_IS_CIPHER
(
cipher
));
klass
=
PURPLE_CIPHER_GET_CLASS
(
cipher
);
if
(
klass
&&
klass
->
set_batch_mode
)
klass
->
set_batch_mode
(
cipher
,
mode
);
else
{
purple_debug_warning
(
"cipher"
,
"the %s cipher does not "
"implement the set_batch_mode method"
,
purple_cipher_get_name
(
cipher
));
}
}
PurpleCipherBatchMode
purple_cipher_get_batch_mode
(
PurpleCipher
*
cipher
)
{
PurpleCipherClass
*
klass
=
NULL
;
g_return_val_if_fail
(
PURPLE_IS_CIPHER
(
cipher
),
-1
);
klass
=
PURPLE_CIPHER_GET_CLASS
(
cipher
);
if
(
klass
&&
klass
->
get_batch_mode
)
return
klass
->
get_batch_mode
(
cipher
);
else
{
purple_debug_warning
(
"cipher"
,
"the %s cipher does not "
"implement the get_batch_mode method"
,
purple_cipher_get_name
(
cipher
));
}
return
-1
;
}
size_t
purple_cipher_get_block_size
(
PurpleCipher
*
cipher
)
{
PurpleCipherClass
*
klass
=
NULL
;
g_return_val_if_fail
(
PURPLE_IS_CIPHER
(
cipher
),
-1
);
klass
=
PURPLE_CIPHER_GET_CLASS
(
cipher
);
if
(
klass
&&
klass
->
get_block_size
)
return
klass
->
get_block_size
(
cipher
);
else
{
purple_debug_warning
(
"cipher"
,
"the %s cipher does not "
"implement the get_block_size method"
,
purple_cipher_get_name
(
cipher
));
}
return
-1
;
}
/******************************************************************************
* PurpleHash API
*****************************************************************************/
GType
purple_hash_get_type
(
void
)
{
static
GType
type
=
0
;
if
(
type
==
0
)
{
static
const
GTypeInfo
info
=
{
sizeof
(
PurpleHashClass
),
NULL
,
NULL
,
NULL
,
NULL
,
NULL
,
sizeof
(
PurpleHash
),
0
,
NULL
,
NULL
};
type
=
g_type_register_static
(
G_TYPE_OBJECT
,
"PurpleHash"
,
&
info
,
G_TYPE_FLAG_ABSTRACT
);
}
return
type
;
}
void
purple_hash_reset
(
PurpleHash
*
hash
)
{
PurpleHashClass
*
klass
=
NULL
;
g_return_if_fail
(
PURPLE_IS_HASH
(
hash
));
klass
=
PURPLE_HASH_GET_CLASS
(
hash
);
if
(
klass
&&
klass
->
reset
)
klass
->
reset
(
hash
);
else
{
purple_debug_warning
(
"hash"
,
"the %s hash does not implement "
"the reset method"
,
purple_hash_get_name
(
hash
));
}
}
void
purple_hash_reset_state
(
PurpleHash
*
hash
)
{
PurpleHashClass
*
klass
=
NULL
;
g_return_if_fail
(
PURPLE_IS_HASH
(
hash
));
klass
=
PURPLE_HASH_GET_CLASS
(
hash
);
if
(
klass
&&
klass
->
reset_state
)
klass
->
reset_state
(
hash
);
else
{
purple_debug_warning
(
"hash"
,
"the %s hash does not implement "
"the reset_state method"
,
purple_hash_get_name
(
hash
));
}
}
void
purple_hash_append
(
PurpleHash
*
hash
,
const
guchar
*
data
,
size_t
len
)
{
PurpleHashClass
*
klass
=
NULL
;
g_return_if_fail
(
PURPLE_IS_HASH
(
hash
));
klass
=
PURPLE_HASH_GET_CLASS
(
hash
);
if
(
klass
&&
klass
->
append
)
klass
->
append
(
hash
,
data
,
len
);
else
{
purple_debug_warning
(
"hash"
,
"the %s hash does not implement "
"the append method"
,
purple_hash_get_name
(
hash
));
}
}
gboolean
purple_hash_digest
(
PurpleHash
*
hash
,
guchar
digest
[],
size_t
len
)
{
PurpleHashClass
*
klass
=
NULL
;
g_return_val_if_fail
(
PURPLE_IS_HASH
(
hash
),
FALSE
);
klass
=
PURPLE_HASH_GET_CLASS
(
hash
);
if
(
klass
&&
klass
->
digest
)
return
klass
->
digest
(
hash
,
digest
,
len
);
else
{
purple_debug_warning
(
"hash"
,
"the %s hash does not implement "
"the digest method"
,
purple_hash_get_name
(
hash
));
}
return
FALSE
;
}
gboolean
purple_hash_digest_to_str
(
PurpleHash
*
hash
,
gchar
digest_s
[],
size_t
len
)
{
/* 8k is a bit excessive, will tweak later. */
guchar
digest
[
BUF_LEN
*
4
];
size_t
digest_size
,
n
;
g_return_val_if_fail
(
PURPLE_IS_HASH
(
hash
),
FALSE
);
g_return_val_if_fail
(
digest_s
,
FALSE
);
digest_size
=
purple_hash_get_digest_size
(
hash
);
g_return_val_if_fail
(
digest_size
<=
BUF_LEN
*
4
,
FALSE
);
if
(
!
purple_hash_digest
(
hash
,
digest
,
sizeof
(
digest
)))
return
FALSE
;
/* Every digest byte occupies 2 chars + the NUL at the end. */
g_return_val_if_fail
(
digest_size
*
2
+
1
<=
len
,
FALSE
);
for
(
n
=
0
;
n
<
digest_size
;
n
++
)
sprintf
(
digest_s
+
(
n
*
2
),
"%02x"
,
digest
[
n
]);
digest_s
[
n
*
2
]
=
'\0'
;
return
TRUE
;
}
size_t
purple_hash_get_digest_size
(
PurpleHash
*
hash
)
{
PurpleHashClass
*
klass
=
NULL
;
g_return_val_if_fail
(
PURPLE_IS_HASH
(
hash
),
FALSE
);
klass
=
PURPLE_HASH_GET_CLASS
(
hash
);
if
(
klass
&&
klass
->
get_digest_size
)
return
klass
->
get_digest_size
(
hash
);
else
{
purple_debug_warning
(
"hash"
,
"the %s hash does not implement "
"the get_digest_size method"
,
purple_hash_get_name
(
hash
));
}
return
FALSE
;
}
size_t
purple_hash_get_block_size
(
PurpleHash
*
hash
)
{
PurpleHashClass
*
klass
=
NULL
;
g_return_val_if_fail
(
PURPLE_IS_HASH
(
hash
),
-1
);
klass
=
PURPLE_HASH_GET_CLASS
(
hash
);
if
(
klass
&&
klass
->
get_block_size
)
return
klass
->
get_block_size
(
hash
);
else
{
purple_debug_warning
(
"hash"
,
"the %s hash does not implement "
"the get_block_size method"
,
purple_hash_get_name
(
hash
));
}
return
-1
;
}