Add uri_str_to_bytes(), byte_array_dup(), and byte_array_equal()

functions to strutil.  Use GByteArrays to store SSIDs for decryption,
and let the user specify arbitrary byte strings using percent-encoded
strings.  We should probably add percent encoding for pass phrases as
well, so you can escape the ":" character.

Move the key struct key conversion utilities to airpdcap.c, and remove
duplicate code from packet-ieee80211.c.  Fix a lot of indentation.

svn path=/trunk/; revision=20388
This commit is contained in:
Gerald Combs 2007-01-11 02:42:34 +00:00
parent 5223c8dfa6
commit 983f496f69
7 changed files with 1489 additions and 1681 deletions

File diff suppressed because it is too large Load Diff

View File

@ -530,17 +530,4 @@ get_compiled_airpcap_version(GString *str);
void
get_runtime_airpcap_version(GString *str);
/*
* Returns the decryption_key_t struct given a string describing the key.
* Returns NULL if the key_string cannot be parsed.
*/
decryption_key_t*
parse_key_string(gchar* key_string);
/*
* Returns a newly allocated string representing the given decryption_key_t struct
*/
gchar*
get_key_string(decryption_key_t* dk);
#endif

View File

@ -3,6 +3,7 @@
#include <epan/tvbuff.h>
#include <epan/crc32.h>
#include <epan/strutil.h>
#include "airpdcap_system.h"
#include "airpdcap_int.h"
@ -12,6 +13,8 @@
#include "airpdcap_debug.h"
#include "wep-wpadefs.h"
/****************************************************************************/
/****************************************************************************/
@ -1282,6 +1285,373 @@ INT AirPDcapRsnaPwd2Psk(
return 0;
}
/*
* Returns the decryption_key_t struct given a string describing the key.
* Returns NULL if the key_string cannot be parsed.
*/
decryption_key_t*
parse_key_string(gchar* input_string)
{
gchar *type;
gchar *key;
gchar *ssid;
GString *key_string = NULL;
GByteArray *ssid_ba = NULL;
gchar **tokens;
guint n = 0;
guint i;
decryption_key_t *dk;
if(input_string == NULL)
return NULL;
/*
* Parse the input_string. It should be in the form
* <key type>:<key data>[:<ssid>]
* XXX - For backward compatibility, the a WEP key can be just a string
* of hexadecimal characters (if WEP key is wrong, null will be
* returned...).
*/
tokens = g_strsplit(input_string,":",0);
/* Tokens is a null termiated array of strings ... */
while(tokens[n] != NULL)
n++;
if(n == 0)
{
/* Free the array of strings */
g_strfreev(tokens);
return NULL;
}
/*
* 'n' contains the number of tokens. If the key string is correct,
* we should have 2 or 3 tokens... If we have 1 token, it can be an
* 'old style' WEP key. Check for it.
*/
if(n == 1)
{
/* Maybe it is an 'old style' WEP key */
key = g_strdup(tokens[0]);
/* Create a new string */
key_string = g_string_new(key);
/* Check if it is a correct WEP key */
if( ((key_string->len) > WEP_KEY_MAX_CHAR_SIZE) || ((key_string->len) < WEP_KEY_MIN_CHAR_SIZE))
{
g_string_free(key_string, TRUE);
g_free(key);
/* Free the array of strings */
g_strfreev(tokens);
return NULL;
}
if((key_string->len % 2) != 0)
{
g_string_free(key_string, TRUE);
g_free(key);
/* Free the array of strings */
g_strfreev(tokens);
return NULL;
}
for(i = 0; i < key_string->len; i++)
{
if(!g_ascii_isxdigit(key_string->str[i]))
{
g_string_free(key_string, TRUE);
g_free(key);
/* Free the array of strings */
g_strfreev(tokens);
return NULL;
}
}
/* Key is correct! It was probably an 'old style' WEP key */
/* Create the decryption_key_t structure, fill it and return it*/
dk = g_malloc(sizeof(decryption_key_t));
dk->type = AIRPDCAP_KEY_TYPE_WEP;
dk->key = g_string_new(key);
dk->bits = dk->key->len * 4;
dk->ssid = NULL;
g_string_free(key_string, TRUE);
g_free(key);
/* Free the array of strings */
g_strfreev(tokens);
return dk;
}
/* There were at least 2 tokens... copy the type value */
type = g_strdup(tokens[0]);
/*
* The second token is the key (right now it doesn't matter
* if it is a passphrase or an hexadecimal one)
*/
key = g_strdup(tokens[1]);
/* Lower case the type */
g_strdown(type);
/* Maybe there is a third token (an ssid, if everything else is ok) */
if(n >= 3)
{
ssid = g_strdup(tokens[2]);
}
else
{
ssid = NULL;
}
/*
* Now the initial key string has been divided in two/three tokens.
* Let's see which kind of key it is, and if it is the correct form
*/
if(g_strcasecmp(type,STRING_KEY_TYPE_WEP) == 0) /* WEP key */
{
/* Create a new string */
key_string = g_string_new(key);
/* Check if it is a correct WEP key */
if( ((key_string->len) > WEP_KEY_MAX_CHAR_SIZE) || ((key_string->len) < WEP_KEY_MIN_CHAR_SIZE))
{
g_string_free(key_string, TRUE);
g_free(key);
/* Free the array of strings */
g_strfreev(tokens);
return NULL;
}
if((key_string->len % 2) != 0)
{
g_string_free(key_string, TRUE);
g_free(key);
/* Free the array of strings */
g_strfreev(tokens);
return NULL;
}
for(i = 0; i < key_string->len; i++)
{
if(!g_ascii_isxdigit(key_string->str[i]))
{
g_string_free(key_string, TRUE);
g_free(key);
/* Free the array of strings */
g_strfreev(tokens);
return NULL;
}
}
dk = (decryption_key_t*)g_malloc(sizeof(decryption_key_t));
dk->type = AIRPDCAP_KEY_TYPE_WEP;
dk->key = g_string_new(key);
dk->bits = dk->key->len * 4;
dk->ssid = NULL;
g_string_free(key_string, TRUE);
g_free(key);
/* Free the array of strings */
g_strfreev(tokens);
return dk;
}
else if(g_strcasecmp(type,STRING_KEY_TYPE_WPA_PSK) == 0) /* WPA key */
{
/* Create a new string */
key_string = g_string_new(key);
/* Two tokens means that the user should have entered a WPA-BIN key ... */
if( ((key_string->len) != WPA_PSK_KEY_CHAR_SIZE))
{
g_string_free(key_string, TRUE);
g_free(type);
g_free(key);
/* No ssid has been created ... */
/* Free the array of strings */
g_strfreev(tokens);
return NULL;
}
for(i = 0; i < key_string->len; i++)
{
if(!g_ascii_isxdigit(key_string->str[i]))
{
g_string_free(key_string, TRUE);
/* No ssid_string has been created ... */
g_free(type);
g_free(key);
/* No ssid has been created ... */
/* Free the array of strings */
g_strfreev(tokens);
return NULL;
}
}
/* Key was correct!!! Create the new decryption_key_t ... */
dk = (decryption_key_t*)g_malloc(sizeof(decryption_key_t));
dk->type = AIRPDCAP_KEY_TYPE_WPA_PMK;
dk->key = g_string_new(key);
dk->bits = dk->key->len * 4;
dk->ssid = NULL;
g_string_free(key_string, TRUE);
g_free(key);
g_free(type);
/* Free the array of strings */
g_strfreev(tokens);
return dk;
}
else if(g_strcasecmp(type,STRING_KEY_TYPE_WPA_PWD) == 0) /* WPA key *//* If the number of tokens is more than three, we accept the string... if the first three tokens are correct... */
{
/* Create a new string */
key_string = g_string_new(key);
ssid_ba = NULL;
/* Three (or more) tokens mean that the user entered a WPA-PWD key ... */
if( ((key_string->len) > WPA_KEY_MAX_CHAR_SIZE) || ((key_string->len) < WPA_KEY_MIN_CHAR_SIZE))
{
g_string_free(key_string, TRUE);
g_free(type);
g_free(key);
g_free(ssid);
/* Free the array of strings */
g_strfreev(tokens);
return NULL;
}
if(ssid != NULL) /* more than three tokens found, means that the user specified the ssid */
{
ssid_ba = g_byte_array_new();
if (! uri_str_to_bytes(ssid, ssid_ba)) {
g_string_free(key_string, TRUE);
g_byte_array_free(ssid_ba, TRUE);
g_free(type);
g_free(key);
g_free(ssid);
/* Free the array of strings */
g_strfreev(tokens);
return NULL;
}
/*
* XXX - Maybe we need some check on the characters? I'm not sure if only standard ASCII are ok...
*/
if(ssid_ba->len > WPA_SSID_MAX_CHAR_SIZE)
{
g_string_free(key_string, TRUE);
g_byte_array_free(ssid_ba, TRUE);
g_free(type);
g_free(key);
g_free(ssid);
/* Free the array of strings */
g_strfreev(tokens);
return NULL;
}
}
/* Key was correct!!! Create the new decryption_key_t ... */
dk = (decryption_key_t*)g_malloc(sizeof(decryption_key_t));
dk->type = AIRPDCAP_KEY_TYPE_WPA_PWD;
dk->key = g_string_new(key);
dk->bits = 256; /* This is the lenght of the array pf bytes that will be generated using key+ssid ...*/
if(ssid != NULL)
dk->ssid = byte_array_dup(ssid_ba);
g_string_free(key_string, TRUE);
if (ssid_ba != NULL)
g_byte_array_free(ssid_ba, TRUE);
g_free(type);
g_free(key);
if(ssid != NULL) g_free(ssid);
/* Free the array of strings */
g_strfreev(tokens);
return dk;
}
/* Something was wrong ... free everything */
g_free(type);
g_free(key);
if(ssid != NULL) g_free(ssid); /* It is not always present */
/* Free the array of strings */
g_strfreev(tokens);
return NULL;
}
/*
* Returns a newly allocated string representing the given decryption_key_t
* struct, or NULL if something is wrong...
*/
gchar*
get_key_string(decryption_key_t* dk)
{
gchar* output_string = NULL;
if(dk == NULL)
return NULL;
#ifdef HAVE_AIRPDCAP
if(dk->type == AIRPDCAP_KEY_TYPE_WEP)
{
if(dk->key == NULL) /* Should NOT happen at all... */
return NULL;
output_string = g_strdup_printf("%s:%s",STRING_KEY_TYPE_WEP,dk->key->str);
}
else if(dk->type == AIRPDCAP_KEY_TYPE_WPA_PWD)
{
if(dk->key == NULL) /* Should NOT happen at all... */
return NULL;
if(dk->ssid == NULL)
output_string = g_strdup_printf("%s:%s",STRING_KEY_TYPE_WPA_PWD,dk->key->str);
else
output_string = g_strdup_printf("%s:%s:%s",
STRING_KEY_TYPE_WPA_PWD,dk->key->str,
format_text((guchar *)dk->ssid->data, dk->ssid->len);
}
else if(dk->type == AIRPDCAP_KEY_TYPE_WPA_PMK)
{
if(dk->key == NULL) /* Should NOT happen at all... */
return NULL;
output_string = g_strdup_printf("%s:%s",STRING_KEY_TYPE_WPA_PSK,dk->key->str);
}
else
{
return NULL;
}
#else /* not HAVE_AIRPDCAP*/
output_string = g_strdup(dk->key->str);
#endif
return output_string;
}
#ifdef __cplusplus
}
#endif

View File

@ -51,10 +51,10 @@
* Struct to store info about a specific decryption key.
*/
typedef struct {
GString *key;
GString *ssid;
guint bits;
guint type;
GString *key;
GByteArray *ssid;
guint bits;
guint type;
} decryption_key_t;
/**
@ -159,9 +159,20 @@ typedef struct _AIRPDCAP_KEYS_COLLECTION {
/******************************************************************************/
/* Function prototype declarations */
/* */
/* */
/* */
/*
* Returns the decryption_key_t struct given a string describing the key.
* Returns NULL if the key_string cannot be parsed.
*/
decryption_key_t*
parse_key_string(gchar* key_string);
/*
* Returns a newly allocated string representing the given decryption_key_t struct
*/
gchar*
get_key_string(decryption_key_t* dk);
/******************************************************************************/
#endif /* _AIRPDCAP_USER_H */

View File

@ -5024,9 +5024,9 @@ proto_register_ieee80211 (void)
g_string_sprintf(key_desc,
"Key #%d string can be:"
" <wep hexadecimal key>;"
" WEP:<wep hexadecimal key>;"
" WPA-PWD:<passphrase>[:<ssid>];"
" WPA-PSK:<wpa hexadecimal key>", i + 1);
" wep:<wep hexadecimal key>;"
" wpa-pwd:<passphrase>[:<ssid>];"
" wpa-psk:<wpa hexadecimal key>", i + 1);
#else
g_string_sprintf(key_name, "wep_key%d", i + 1);
g_string_sprintf(key_title, "WEP key #%d", i + 1);
@ -5169,321 +5169,11 @@ static tvbuff_t *try_decrypt_wep(tvbuff_t *tvb, guint32 offset, guint32 len) {
return decr_tvb;
}
#ifdef HAVE_AIRPDCAP
/*
* Returns the decryption_key_t struct given a string describing the key.
* Returns NULL if the key_string cannot be parsed.
*/
static decryption_key_t*
parse_key(gchar* input_string)
{
gchar *type;
gchar *key;
gchar *ssid;
GString *key_string,
*ssid_string;
gchar **tokens;
guint n = 0;
guint i;
decryption_key_t *dk;
if(input_string == NULL)
return NULL;
/*
* Parse the input_string. It should be in the form <key type>:<key data>[:<ssid>]
* XXX - For backward compatibility, the a WEP key can be just a string of hexadecimal
* characters (if WEP key is wrong, null will be returned...).
*/
tokens = g_strsplit(input_string,":",0);
/* Tokens is a null termiated array of strings ... */
while(tokens[n] != NULL)
n++;
if(n == 0)
{
/* Free the array of strings */
g_strfreev(tokens);
return NULL;
}
/*
* 'n' contains the number of tokens. If the key string is correct, we should have
* 2 or 3 tokens... If we have 1 token, it can be an 'old style' WEP key... check for it...
*/
if(n == 1)
{
/* Maybe it is an 'old style' WEP key */
key = g_strdup(tokens[0]);
/* Create a new string */
key_string = g_string_new(key);
/* Check if it is a correct WEP key */
if( ((key_string->len) > WEP_KEY_MAX_CHAR_SIZE) || ((key_string->len) < WEP_KEY_MIN_CHAR_SIZE))
{
g_string_free(key_string, TRUE);
g_free(key);
/* Free the array of strings */
g_strfreev(tokens);
return NULL;
}
if((key_string->len % 2) != 0)
{
g_string_free(key_string, TRUE);
g_free(key);
/* Free the array of strings */
g_strfreev(tokens);
return NULL;
}
for(i = 0; i < key_string->len; i++)
{
if(!g_ascii_isxdigit(key_string->str[i]))
{
g_string_free(key_string, TRUE);
g_free(key);
/* Free the array of strings */
g_strfreev(tokens);
return NULL;
}
}
/* Key is correct! It was probably an 'old style' WEP key */
/* Create the decryption_key_t structure, fill it and return it*/
dk = g_malloc(sizeof(decryption_key_t));
dk->type = AIRPDCAP_KEY_TYPE_WEP;
dk->key = g_string_new(key);
dk->bits = dk->key->len * 4;
dk->ssid = NULL;
g_string_free(key_string, TRUE);
g_free(key);
/* Free the array of strings */
g_strfreev(tokens);
return dk;
}
/* There were at least 2 tokens... copy the type value */
type = g_strdup(tokens[0]);
/*
* The second token is the key (right now it doesn't matter
* if it is a passphrase or an hexadecimal one)
*/
key = g_strdup(tokens[1]);
/* Lower case... */
g_strdown(type);
/* Maybe there is a third token (an ssid, if everything else is ok) */
if(n >= 3)
{
ssid = g_strdup(tokens[2]);
}
else
{
ssid = NULL;
}
/*
* Now the initial key string has been divided in two/three tokens... let's see
* which kind of key it is, and if it is the correct form
*/
if(g_strcasecmp(type,STRING_KEY_TYPE_WEP) == 0) /* WEP key */
{
/* Create a new string */
key_string = g_string_new(key);
/* Check if it is a correct WEP key */
if( ((key_string->len) > WEP_KEY_MAX_CHAR_SIZE) || ((key_string->len) < WEP_KEY_MIN_CHAR_SIZE))
{
g_string_free(key_string, TRUE);
g_free(key);
/* Free the array of strings */
g_strfreev(tokens);
return NULL;
}
if((key_string->len % 2) != 0)
{
g_string_free(key_string, TRUE);
g_free(key);
/* Free the array of strings */
g_strfreev(tokens);
return NULL;
}
for(i = 0; i < key_string->len; i++)
{
if(!g_ascii_isxdigit(key_string->str[i]))
{
g_string_free(key_string, TRUE);
g_free(key);
/* Free the array of strings */
g_strfreev(tokens);
return NULL;
}
}
dk = (decryption_key_t*)g_malloc(sizeof(decryption_key_t));
dk->type = AIRPDCAP_KEY_TYPE_WEP;
dk->key = g_string_new(key);
dk->bits = dk->key->len * 4;
dk->ssid = NULL;
g_string_free(key_string, TRUE);
g_free(key);
/* Free the array of strings */
g_strfreev(tokens);
return dk;
}
else if(g_strcasecmp(type,STRING_KEY_TYPE_WPA_PSK) == 0) /* WPA key */
{
/* Create a new string */
key_string = g_string_new(key);
/* Two tokens means that the user should have entered a WPA-BIN key ... */
if( ((key_string->len) != WPA_PSK_KEY_CHAR_SIZE))
{
g_string_free(key_string, TRUE);
g_free(type);
g_free(key);
/* No ssid has been created ... */
/* Free the array of strings */
g_strfreev(tokens);
return NULL;
}
for(i = 0; i < key_string->len; i++)
{
if(!g_ascii_isxdigit(key_string->str[i]))
{
g_string_free(key_string, TRUE);
/* No ssid_string has been created ... */
g_free(type);
g_free(key);
/* No ssid has been created ... */
/* Free the array of strings */
g_strfreev(tokens);
return NULL;
}
}
/* Key was correct!!! Create the new decryption_key_t ... */
dk = (decryption_key_t*)g_malloc(sizeof(decryption_key_t));
dk->type = AIRPDCAP_KEY_TYPE_WPA_PMK;
dk->key = g_string_new(key);
dk->bits = dk->key->len * 4;
dk->ssid = NULL;
g_string_free(key_string, TRUE);
g_free(key);
g_free(type);
/* Free the array of strings */
g_strfreev(tokens);
return dk;
}
else if(g_strcasecmp(type,STRING_KEY_TYPE_WPA_PWD) == 0) /* WPA key *//* If the number of tokens is more than three, we accept the string... if the first three tokens are correct... */
{
/* Create a new string */
key_string = g_string_new(key);
ssid_string = NULL;
/* Three (or more) tokens mean that the user entered a WPA-PWD key ... */
if( ((key_string->len) > WPA_KEY_MAX_CHAR_SIZE) || ((key_string->len) < WPA_KEY_MIN_CHAR_SIZE))
{
g_string_free(key_string, TRUE);
g_free(type);
g_free(key);
g_free(ssid);
/* Free the array of strings */
g_strfreev(tokens);
return NULL;
}
if(ssid != NULL) /* more than three tokens found, means that the user specified the ssid */
{
ssid_string = g_string_new(ssid);
/*
* XXX - Maybe we need some check on the characters? I'm not sure if only standard ASCII are ok...
*/
if( ((ssid_string->len) > WPA_SSID_MAX_CHAR_SIZE) || ((ssid_string->len) < WPA_SSID_MIN_CHAR_SIZE))
{
g_string_free(key_string, TRUE);
g_string_free(ssid_string, TRUE);
g_free(type);
g_free(key);
g_free(ssid);
/* Free the array of strings */
g_strfreev(tokens);
return NULL;
}
}
/* Key was correct!!! Create the new decryption_key_t ... */
dk = (decryption_key_t*)g_malloc(sizeof(decryption_key_t));
dk->type = AIRPDCAP_KEY_TYPE_WPA_PWD;
dk->key = g_string_new(key);
dk->bits = 256; /* This is the lenght of the array pf bytes that will be generated using key+ssid ...*/
if(ssid != NULL)
dk->ssid = g_string_new(ssid);
else
dk->ssid = NULL;
g_string_free(key_string, TRUE);
if(ssid_string != NULL) g_string_free(ssid_string, TRUE);
g_free(type);
g_free(key);
if(ssid != NULL) g_free(ssid);
/* Free the array of strings */
g_strfreev(tokens);
return dk;
}
/* Something was wrong ... free everything */
g_free(type);
g_free(key);
if(ssid != NULL) g_free(ssid); /* It is not always present */
/* Free the array of strings */
g_strfreev(tokens);
return NULL;
}
#endif
#ifdef HAVE_AIRPDCAP
static
void set_airpdcap_keys()
{
guint n = 0;
guint i = 0;
guint nKeys = 0;
AIRPDCAP_KEY_ITEM key;
PAIRPDCAP_KEYS_COLLECTION keys;
decryption_key_t* dk = NULL;
@ -5498,7 +5188,7 @@ void set_airpdcap_keys()
{
tmpk = g_strdup(wep_keystr[i]);
dk = parse_key(tmpk);
dk = parse_key_string(tmpk);
if(dk != NULL)
{
@ -5533,7 +5223,7 @@ void set_airpdcap_keys()
{
if(dk->ssid->len > 0)
{
memcpy(key.KeyData.Wpa.UserPwd.Ssid,dk->ssid->str,dk->ssid->len+1);
memcpy(key.KeyData.Wpa.UserPwd.Ssid,dk->ssid->data,dk->ssid->len);
key.KeyData.Wpa.UserPwd.SsidLen = dk->ssid->len;
}
else /* The GString is not NULL, but the 'ssid' name is just "\0" */

View File

@ -505,6 +505,67 @@ hex_str_to_bytes(const char *hex_str, GByteArray *bytes, gboolean force_separato
return TRUE;
}
/*
* Turn an RFC 3986 percent-encoded string into a byte array.
* XXX - We don't check for reserved characters.
*/
#define HEX_DIGIT_BUF_LEN 3
gboolean
uri_str_to_bytes(const char *uri_str, GByteArray *bytes) {
guint8 val;
const char *p;
char hex_digit[HEX_DIGIT_BUF_LEN];
g_byte_array_set_size(bytes, 0);
if (! uri_str) {
return FALSE;
}
p = uri_str;
while (*p) {
if (! isascii(*p) || ! isprint(*p))
return FALSE;
if (*p == '%') {
p++;
g_strlcpy(hex_digit, p, HEX_DIGIT_BUF_LEN);
if (strlen(hex_digit) != 2)
return FALSE;
if (! isxdigit(hex_digit[0]) || ! isxdigit(hex_digit[1]))
return FALSE;
val = (guint8) strtoul(hex_digit, NULL, 16);
g_byte_array_append(bytes, &val, 1);
p ++;
} else {
g_byte_array_append(bytes, (guint8 *) p, 1);
}
p++;
}
g_warning("ba %s len: %d", format_text(bytes->data, bytes->len), bytes->len);
return TRUE;
}
/**
* Create a copy of a GByteArray
*
* @param ba The byte array to be copied.
* @return If ba exists, a freshly allocated copy. NULL otherwise.
*
* XXX - Should this be in strutil.c?
*/
GByteArray *
byte_array_dup(GByteArray *ba) {
GByteArray *new_ba;
if (!ba)
return NULL;
new_ba = g_byte_array_new();
g_byte_array_append(new_ba, ba->data, ba->len);
return new_ba;
}
#define SUBID_BUF_LEN 5
gboolean
oid_str_to_bytes(const char *oid_str, GByteArray *bytes) {
@ -563,6 +624,31 @@ oid_str_to_bytes(const char *oid_str, GByteArray *bytes) {
return TRUE;
}
/**
* Compare the contents of two GByteArrays
*
* @param ba1 A byte array
* @param ba2 A byte array
* @return If both arrays are non-NULL and their lengths are equal and
* their contents are equal, returns TRUE. Otherwise, returns
* FALSE.
*
* XXX - Should this be in strutil.c?
*/
gboolean
byte_array_equal(GByteArray *ba1, GByteArray *ba2) {
if (!ba1 || !ba2)
return FALSE;
if (ba1->len != ba2->len)
return FALSE;
if (memcmp(ba1->data, ba2->data, ba1->len) != 0)
return FALSE;
return TRUE;
}
/* Return a XML escaped representation of the unescaped string.
* The returned string must be freed when no longer in use. */

View File

@ -101,6 +101,15 @@ gchar* bytes_to_str_punct(const guint8 *bd, int bd_len, gchar punct);
gboolean hex_str_to_bytes(const char *hex_str, GByteArray *bytes,
gboolean force_separators);
/** Turn an RFC 3986 percent-encoded string into a byte array.
*
* @param uri_str The string of hex digits.
* @param bytes The GByteArray that will receive the bytes. This
* must be initialized by the caller.
* @return True if the string was converted successfully
*/
gboolean uri_str_to_bytes(const char *uri_str, GByteArray *bytes);
/** Turn a OID string representation (dot notaion) into a byte array.
*
* @param oid_str The OID string (dot notaion).
@ -110,6 +119,30 @@ gboolean hex_str_to_bytes(const char *hex_str, GByteArray *bytes,
*/
gboolean oid_str_to_bytes(const char *oid_str, GByteArray *bytes);
/**
* Create a copy of a GByteArray
*
* @param ba The byte array to be copied.
* @return If ba exists, a freshly allocated copy. NULL otherwise.
*
* XXX - Should this be in strutil.c?
*/
GByteArray *byte_array_dup(GByteArray *ba);
/**
* Compare the contents of two GByteArrays
*
* @param ba1 A byte array
* @param ba2 A byte array
* @return If both arrays are non-NULL and their lengths are equal and
* their contents are equal, returns TRUE. Otherwise, returns
* FALSE.
*
* XXX - Should this be in strutil.c?
*/
gboolean byte_array_equal(GByteArray *ba1, GByteArray *ba2);
/** Return a XML escaped representation of the unescaped string.
* The returned string must be freed when no longer in use.
*
@ -118,7 +151,8 @@ gboolean oid_str_to_bytes(const char *oid_str, GByteArray *bytes);
*/
gchar* xml_escape(const gchar *unescaped);
/* Return the first occurrence of needle in haystack.
/**
* Return the first occurrence of needle in haystack.
* Algorithm copied from GNU's glibc 2.3.2 memcmp()
*
* @param haystack The data to search