2
0

Marshal data API & fixes.

This commit is contained in:
Maarten Billemont 2019-07-28 12:35:36 -04:00
parent ddb786c332
commit 4c6d7ac36c
11 changed files with 447 additions and 144 deletions

View File

@ -272,7 +272,7 @@ void cli_free(Arguments *args, Operation *operation) {
mpw_free_strings( &operation->fullName, &operation->masterPassword, &operation->siteName, NULL ); mpw_free_strings( &operation->fullName, &operation->masterPassword, &operation->siteName, NULL );
mpw_free_strings( &operation->keyContext, &operation->resultState, &operation->resultParam, NULL ); mpw_free_strings( &operation->keyContext, &operation->resultState, &operation->resultParam, NULL );
mpw_free_strings( &operation->identicon, &operation->sitesPath, NULL ); mpw_free_strings( &operation->identicon, &operation->sitesPath, NULL );
mpw_marshal_free( &operation->file ); mpw_marshal_file_free( &operation->file );
operation->site = NULL; operation->site = NULL;
operation->question = NULL; operation->question = NULL;
cli_masterKeyProvider_free(); cli_masterKeyProvider_free();
@ -487,7 +487,7 @@ void cli_user(Arguments *args, Operation *operation) {
if (!sitesFile) { if (!sitesFile) {
// If no user from mpsites, create a new one. // If no user from mpsites, create a new one.
mpw_free_string( &operation->sitesPath ); mpw_free_string( &operation->sitesPath );
mpw_marshal_free( &operation->file ); mpw_marshal_file_free( &operation->file );
operation->file = mpw_marshal_file( mpw_marshal_user( operation->file = mpw_marshal_file( mpw_marshal_user(
operation->fullName, cli_masterKeyProvider_op( operation ), MPAlgorithmVersionCurrent ), NULL ); operation->fullName, cli_masterKeyProvider_op( operation ), MPAlgorithmVersionCurrent ), NULL );
} }
@ -501,7 +501,7 @@ void cli_user(Arguments *args, Operation *operation) {
// Parse file. // Parse file.
MPMarshalError marshalError = { .type = MPMarshalSuccess }; MPMarshalError marshalError = { .type = MPMarshalSuccess };
mpw_marshal_free( &operation->file ); mpw_marshal_file_free( &operation->file );
operation->file = mpw_marshal_read( sitesInputData, operation->file = mpw_marshal_read( sitesInputData,
cli_masterKeyProvider_op( operation ), &marshalError ); cli_masterKeyProvider_op( operation ), &marshalError );
if (marshalError.type == MPMarshalErrorMasterPassword && operation->allowPasswordUpdate) { if (marshalError.type == MPMarshalErrorMasterPassword && operation->allowPasswordUpdate) {
@ -516,7 +516,7 @@ void cli_user(Arguments *args, Operation *operation) {
importMasterPassword = mpw_getpass( "Old master password: " ); importMasterPassword = mpw_getpass( "Old master password: " );
} }
mpw_marshal_free( &operation->file ); mpw_marshal_file_free( &operation->file );
operation->file = mpw_marshal_read( sitesInputData, operation->file = mpw_marshal_read( sitesInputData,
cli_masterKeyProvider_str( importMasterPassword ), &marshalError ); cli_masterKeyProvider_str( importMasterPassword ), &marshalError );
if (operation->file && operation->file->user) if (operation->file && operation->file->user)

View File

@ -22,7 +22,7 @@
#include "mpw-algorithm_v2.c" #include "mpw-algorithm_v2.c"
#include "mpw-algorithm_v3.c" #include "mpw-algorithm_v3.c"
MPMasterKey mpw_master_key(const char *fullName, const char *masterPassword, const MPAlgorithmVersion algorithmVersion) { const MPMasterKey mpw_master_key(const char *fullName, const char *masterPassword, const MPAlgorithmVersion algorithmVersion) {
if (fullName && !strlen( fullName )) if (fullName && !strlen( fullName ))
fullName = NULL; fullName = NULL;
@ -56,8 +56,8 @@ MPMasterKey mpw_master_key(const char *fullName, const char *masterPassword, con
} }
} }
MPSiteKey mpw_site_key( const MPSiteKey mpw_site_key(
MPMasterKey masterKey, const char *siteName, const MPCounterValue siteCounter, const MPMasterKey masterKey, const char *siteName, const MPCounterValue siteCounter,
const MPKeyPurpose keyPurpose, const char *keyContext, const MPAlgorithmVersion algorithmVersion) { const MPKeyPurpose keyPurpose, const char *keyContext, const MPAlgorithmVersion algorithmVersion) {
if (keyContext && !strlen( keyContext )) if (keyContext && !strlen( keyContext ))
@ -93,7 +93,7 @@ MPSiteKey mpw_site_key(
} }
const char *mpw_site_result( const char *mpw_site_result(
MPMasterKey masterKey, const char *siteName, const MPCounterValue siteCounter, const MPMasterKey masterKey, const char *siteName, const MPCounterValue siteCounter,
const MPKeyPurpose keyPurpose, const char *keyContext, const MPKeyPurpose keyPurpose, const char *keyContext,
const MPResultType resultType, const char *resultParam, const MPResultType resultType, const char *resultParam,
const MPAlgorithmVersion algorithmVersion) { const MPAlgorithmVersion algorithmVersion) {
@ -171,7 +171,7 @@ const char *mpw_site_result(
} }
const char *mpw_site_state( const char *mpw_site_state(
MPMasterKey masterKey, const char *siteName, const MPCounterValue siteCounter, const MPMasterKey masterKey, const char *siteName, const MPCounterValue siteCounter,
const MPKeyPurpose keyPurpose, const char *keyContext, const MPKeyPurpose keyPurpose, const char *keyContext,
const MPResultType resultType, const char *resultParam, const MPResultType resultType, const char *resultParam,
const MPAlgorithmVersion algorithmVersion) { const MPAlgorithmVersion algorithmVersion) {
@ -223,7 +223,7 @@ static const char *mpw_identicon_accessories[] = {
"", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", ""
}; };
MPIdenticon mpw_identicon(const char *fullName, const char *masterPassword) { const MPIdenticon mpw_identicon(const char *fullName, const char *masterPassword) {
const uint8_t *seed = NULL; const uint8_t *seed = NULL;
if (fullName && strlen( fullName ) && masterPassword && strlen( masterPassword )) if (fullName && strlen( fullName ) && masterPassword && strlen( masterPassword ))
@ -246,7 +246,7 @@ MPIdenticon mpw_identicon(const char *fullName, const char *masterPassword) {
} }
const char *mpw_identicon_encode( const char *mpw_identicon_encode(
MPIdenticon identicon) { const MPIdenticon identicon) {
if (identicon.color == MPIdenticonColorUnset) if (identicon.color == MPIdenticonColorUnset)
return ""; return "";
@ -255,7 +255,7 @@ const char *mpw_identicon_encode(
identicon.color, identicon.leftArm, identicon.body, identicon.rightArm, identicon.accessory ); identicon.color, identicon.leftArm, identicon.body, identicon.rightArm, identicon.accessory );
} }
MPIdenticon mpw_identicon_encoded( const MPIdenticon mpw_identicon_encoded(
const char *encoding) { const char *encoding) {
MPIdenticon identicon = MPIdenticonUnset; MPIdenticon identicon = MPIdenticonUnset;

View File

@ -38,20 +38,20 @@ typedef mpw_enum( unsigned int, MPAlgorithmVersion ) {
/** Derive the master key for a user based on their name and master password. /** Derive the master key for a user based on their name and master password.
* @return A buffer (allocated, MPMasterKeySize) or NULL if the fullName or masterPassword is missing, the algorithm is unknown, or an algorithm error occurred. */ * @return A buffer (allocated, MPMasterKeySize) or NULL if the fullName or masterPassword is missing, the algorithm is unknown, or an algorithm error occurred. */
MPMasterKey mpw_master_key( const MPMasterKey mpw_master_key(
const char *fullName, const char *masterPassword, const MPAlgorithmVersion algorithmVersion); const char *fullName, const char *masterPassword, const MPAlgorithmVersion algorithmVersion);
/** Derive the site key for a user's site from the given master key and site parameters. /** Derive the site key for a user's site from the given master key and site parameters.
* @return A buffer (allocated, MPSiteKeySize) or NULL if the masterKey or siteName is missing, the algorithm is unknown, or an algorithm error occurred. */ * @return A buffer (allocated, MPSiteKeySize) or NULL if the masterKey or siteName is missing, the algorithm is unknown, or an algorithm error occurred. */
MPSiteKey mpw_site_key( const MPSiteKey mpw_site_key(
MPMasterKey masterKey, const char *siteName, const MPCounterValue siteCounter, const MPMasterKey masterKey, const char *siteName, const MPCounterValue siteCounter,
const MPKeyPurpose keyPurpose, const char *keyContext, const MPAlgorithmVersion algorithmVersion); const MPKeyPurpose keyPurpose, const char *keyContext, const MPAlgorithmVersion algorithmVersion);
/** Generate a site result token from the given parameters. /** Generate a site result token from the given parameters.
* @param resultParam A parameter for the resultType. For stateful result types, the output of mpw_site_state. * @param resultParam A parameter for the resultType. For stateful result types, the output of mpw_site_state.
* @return A string (allocated) or NULL if the masterKey or siteName is missing, the algorithm is unknown, or an algorithm error occurred. */ * @return A string (allocated) or NULL if the masterKey or siteName is missing, the algorithm is unknown, or an algorithm error occurred. */
const char *mpw_site_result( const char *mpw_site_result(
MPMasterKey masterKey, const char *siteName, const MPCounterValue siteCounter, const MPMasterKey masterKey, const char *siteName, const MPCounterValue siteCounter,
const MPKeyPurpose keyPurpose, const char *keyContext, const MPKeyPurpose keyPurpose, const char *keyContext,
const MPResultType resultType, const char *resultParam, const MPResultType resultType, const char *resultParam,
const MPAlgorithmVersion algorithmVersion); const MPAlgorithmVersion algorithmVersion);
@ -60,19 +60,19 @@ const char *mpw_site_result(
* @param resultParam A parameter for the resultType. For stateful result types, the desired mpw_site_result. * @param resultParam A parameter for the resultType. For stateful result types, the desired mpw_site_result.
* @return A string (allocated) or NULL if the masterKey, siteName or resultParam is missing, the algorithm is unknown, or an algorithm error occurred. */ * @return A string (allocated) or NULL if the masterKey, siteName or resultParam is missing, the algorithm is unknown, or an algorithm error occurred. */
const char *mpw_site_state( const char *mpw_site_state(
MPMasterKey masterKey, const char *siteName, const MPCounterValue siteCounter, const MPMasterKey masterKey, const char *siteName, const MPCounterValue siteCounter,
const MPKeyPurpose keyPurpose, const char *keyContext, const MPKeyPurpose keyPurpose, const char *keyContext,
const MPResultType resultType, const char *resultParam, const MPResultType resultType, const char *resultParam,
const MPAlgorithmVersion algorithmVersion); const MPAlgorithmVersion algorithmVersion);
/** @return An identicon (static) that represents the user's identity. */ /** @return An identicon (static) that represents the user's identity. */
MPIdenticon mpw_identicon( const MPIdenticon mpw_identicon(
const char *fullName, const char *masterPassword); const char *fullName, const char *masterPassword);
/** @return An encoded representation (shared) of the given identicon or an empty string if the identicon is unset. */ /** @return An encoded representation (shared) of the given identicon or an empty string if the identicon is unset. */
const char *mpw_identicon_encode( const char *mpw_identicon_encode(
MPIdenticon identicon); const MPIdenticon identicon);
/** @return An identicon (static) decoded from the given encoded identicon representation or an identicon with empty fields if the identicon could not be parsed. */ /** @return An identicon (static) decoded from the given encoded identicon representation or an identicon with empty fields if the identicon could not be parsed. */
MPIdenticon mpw_identicon_encoded( const MPIdenticon mpw_identicon_encoded(
const char *encoding); const char *encoding);
#endif // _MPW_ALGORITHM_H #endif // _MPW_ALGORITHM_H

View File

@ -23,7 +23,7 @@ MP_LIBS_BEGIN
#include <string.h> #include <string.h>
MP_LIBS_END MP_LIBS_END
char *mpw_get_token(const char **in, const char *eol, char *delim) { char *mpw_get_token(const char **in, const char *eol, const char *delim) {
// Skip leading spaces. // Skip leading spaces.
for (; **in == ' '; ++*in); for (; **in == ' '; ++*in);
@ -60,7 +60,7 @@ time_t mpw_timegm(const char *time) {
#if MPW_JSON #if MPW_JSON
json_object *mpw_get_json_object( json_object *mpw_get_json_object(
json_object *obj, const char *key, bool create) { json_object *obj, const char *key, const bool create) {
if (!obj) if (!obj)
return NULL; return NULL;
@ -86,7 +86,7 @@ const char *mpw_get_json_string(
} }
int64_t mpw_get_json_int( int64_t mpw_get_json_int(
json_object *obj, const char *key, int64_t defaultValue) { json_object *obj, const char *key, const int64_t defaultValue) {
json_object *json_value = mpw_get_json_object( obj, key, false ); json_object *json_value = mpw_get_json_object( obj, key, false );
if (!json_value) if (!json_value)
@ -96,7 +96,7 @@ int64_t mpw_get_json_int(
} }
bool mpw_get_json_boolean( bool mpw_get_json_boolean(
json_object *obj, const char *key, bool defaultValue) { json_object *obj, const char *key, const bool defaultValue) {
json_object *json_value = mpw_get_json_object( obj, key, false ); json_object *json_value = mpw_get_json_object( obj, key, false );
if (!json_value) if (!json_value)
@ -107,7 +107,7 @@ bool mpw_get_json_boolean(
#endif #endif
bool mpw_update_master_key(MPMasterKey *masterKey, MPAlgorithmVersion *masterKeyAlgorithm, MPAlgorithmVersion targetKeyAlgorithm, bool mpw_update_master_key(MPMasterKey *masterKey, MPAlgorithmVersion *masterKeyAlgorithm, const MPAlgorithmVersion targetKeyAlgorithm,
const char *fullName, const char *masterPassword) { const char *fullName, const char *masterPassword) {
if (masterKey && (!*masterKey || *masterKeyAlgorithm != targetKeyAlgorithm)) { if (masterKey && (!*masterKey || *masterKeyAlgorithm != targetKeyAlgorithm)) {

View File

@ -34,7 +34,7 @@ MP_LIBS_END
* The input string reference is advanced beyond the token delimitor if one is found. * The input string reference is advanced beyond the token delimitor if one is found.
* @return A string (allocated) containing the token or NULL if the delim wasn't found before eol. */ * @return A string (allocated) containing the token or NULL if the delim wasn't found before eol. */
char *mpw_get_token( char *mpw_get_token(
const char **in, const char *eol, char *delim); const char **in, const char *eol, const char *delim);
/** Convert an RFC 3339 time string into epoch time. /** Convert an RFC 3339 time string into epoch time.
* @return ERR if the string could not be parsed. */ * @return ERR if the string could not be parsed. */
time_t mpw_timegm( time_t mpw_timegm(
@ -48,7 +48,7 @@ time_t mpw_timegm(
* @param create If true, create and insert new objects for any missing path components. * @param create If true, create and insert new objects for any missing path components.
* @return An object (shared) or a new object (shared) installed in the tree if the path's object path was not found. */ * @return An object (shared) or a new object (shared) installed in the tree if the path's object path was not found. */
json_object *mpw_get_json_object( json_object *mpw_get_json_object(
json_object *obj, const char *key, bool create); json_object *obj, const char *key, const bool create);
/** Search for a string in a JSON object tree. /** Search for a string in a JSON object tree.
* @param key A dot-delimited list of JSON object keys to walk toward the child object. * @param key A dot-delimited list of JSON object keys to walk toward the child object.
* @return A string (shared) or defaultValue if one of the path's object keys was not found in the source object's tree. */ * @return A string (shared) or defaultValue if one of the path's object keys was not found in the source object's tree. */
@ -58,12 +58,12 @@ const char *mpw_get_json_string(
* @param key A dot-delimited list of JSON object keys to walk toward the child object. * @param key A dot-delimited list of JSON object keys to walk toward the child object.
* @return The integer value or defaultValue if one of the path's object keys was not found in the source object's tree. */ * @return The integer value or defaultValue if one of the path's object keys was not found in the source object's tree. */
int64_t mpw_get_json_int( int64_t mpw_get_json_int(
json_object *obj, const char *key, int64_t defaultValue); json_object *obj, const char *key, const int64_t defaultValue);
/** Search for a boolean in a JSON object tree. /** Search for a boolean in a JSON object tree.
* @param key A dot-delimited list of JSON object keys to walk toward the child object. * @param key A dot-delimited list of JSON object keys to walk toward the child object.
* @return The boolean value or defaultValue if one of the path's object keys was not found in the source object's tree. */ * @return The boolean value or defaultValue if one of the path's object keys was not found in the source object's tree. */
bool mpw_get_json_boolean( bool mpw_get_json_boolean(
json_object *obj, const char *key, bool defaultValue); json_object *obj, const char *key, const bool defaultValue);
#endif #endif
/// mpw. /// mpw.
@ -72,7 +72,7 @@ bool mpw_get_json_boolean(
* @param masterKey A buffer (allocated, MPMasterKeySize). * @param masterKey A buffer (allocated, MPMasterKeySize).
* @return false if an error occurred during the derivation of the master key. */ * @return false if an error occurred during the derivation of the master key. */
bool mpw_update_master_key( bool mpw_update_master_key(
MPMasterKey *masterKey, MPAlgorithmVersion *masterKeyAlgorithm, MPAlgorithmVersion targetKeyAlgorithm, MPMasterKey *masterKey, MPAlgorithmVersion *masterKeyAlgorithm, const MPAlgorithmVersion targetKeyAlgorithm,
const char *fullName, const char *masterPassword); const char *fullName, const char *masterPassword);
#endif // _MPW_MARSHAL_UTIL_H #endif // _MPW_MARSHAL_UTIL_H

View File

@ -120,75 +120,309 @@ MPMarshalledFile *mpw_marshal_file(
return file; return file;
} }
bool mpw_marshal_info_free( void mpw_marshal_info_free(
MPMarshalInfo **info) { MPMarshalInfo **info) {
if (!info || !*info) if (!info || !*info)
return true; return;
bool success = true; mpw_free_strings( &(*info)->fullName, &(*info)->keyID, NULL );
success &= mpw_free_strings( &(*info)->fullName, &(*info)->keyID, NULL ); mpw_free( info, sizeof( MPMarshalInfo ) );
success &= mpw_free( info, sizeof( MPMarshalInfo ) );
return success;
} }
static bool mpw_marshal_user_free( void mpw_marshal_user_free(
MPMarshalledUser **user) { MPMarshalledUser **user) {
if (!user || !*user) if (!user || !*user)
return true; return;
bool success = mpw_free_strings( &(*user)->fullName, &(*user)->keyID, NULL ); mpw_free_strings( &(*user)->fullName, &(*user)->keyID, NULL );
for (size_t s = 0; s < (*user)->sites_count; ++s) { for (size_t s = 0; s < (*user)->sites_count; ++s) {
MPMarshalledSite *site = &(*user)->sites[s]; MPMarshalledSite *site = &(*user)->sites[s];
success &= mpw_free_strings( &site->siteName, &site->resultState, &site->loginState, &site->url, NULL ); mpw_free_strings( &site->siteName, &site->resultState, &site->loginState, &site->url, NULL );
for (size_t q = 0; q < site->questions_count; ++q) { for (size_t q = 0; q < site->questions_count; ++q) {
MPMarshalledQuestion *question = &site->questions[q]; MPMarshalledQuestion *question = &site->questions[q];
success &= mpw_free_strings( &question->keyword, &question->state, NULL ); mpw_free_strings( &question->keyword, &question->state, NULL );
} }
success &= mpw_free( &site->questions, sizeof( MPMarshalledQuestion ) * site->questions_count ); mpw_free( &site->questions, sizeof( MPMarshalledQuestion ) * site->questions_count );
} }
success &= mpw_free( &(*user)->sites, sizeof( MPMarshalledSite ) * (*user)->sites_count ); mpw_free( &(*user)->sites, sizeof( MPMarshalledSite ) * (*user)->sites_count );
success &= mpw_free( user, sizeof( MPMarshalledUser ) ); mpw_free( user, sizeof( MPMarshalledUser ) );
return success;
} }
static bool mpw_marshal_data_null( void mpw_marshal_file_free(
MPMarshalledData *data) {
if (!data)
return true;
bool success = mpw_free_strings( &data->key, &data->str_value, NULL );
for (unsigned int c = 0; c < data->children_count; ++c)
success &= mpw_marshal_data_null( &data->children[c] );
success &= mpw_free( &data->children, sizeof( MPMarshalledData ) * data->children_count );
data->children_count = 0;
data->num_value = NAN;
data->is_bool = false;
data->is_null = true;
return success;
}
bool mpw_marshal_free(
MPMarshalledFile **file) { MPMarshalledFile **file) {
if (!file || !*file) if (!file || !*file)
return;
mpw_marshal_info_free( &(*file)->info );
mpw_marshal_user_free( &(*file)->user );
if ((*file)->data) {
mpw_marshal_data_set_null( (*file)->data, NULL );
mpw_free_string( &(*file)->data->key );
mpw_free( &(*file)->data, sizeof( MPMarshalledData ) );
}
mpw_free( file, sizeof( MPMarshalledFile ) );
}
MPMarshalledData *mpw_marshal_data_new() {
MPMarshalledData *data = malloc( sizeof( MPMarshalledData ) );
*data = (MPMarshalledData){};
mpw_marshal_data_set_null( data, NULL );
return data;
}
MPMarshalledData *mpw_marshal_data_vget(
MPMarshalledData *data, va_list nodes) {
MPMarshalledData *parent = data, *child;
for (const char *node; parent && (node = va_arg( nodes, const char * )); parent = child) {
child = NULL;
for (size_t c = 0; c < parent->children_count; ++c) {
const char *key = parent->children[c].key;
if (key && strcmp( node, key ) == OK) {
child = &parent->children[c];
break;
}
}
if (!child) {
if (!mpw_realloc( &parent->children, NULL, sizeof( MPMarshalledData ) * ++parent->children_count )) {
--parent->children_count;
break;
}
*(child = &parent->children[parent->children_count - 1]) = (MPMarshalledData){ .key = mpw_strdup( node ) };
mpw_marshal_data_set_null( child, NULL );
child->is_null = false;
}
}
return parent;
}
MPMarshalledData *mpw_marshal_data_get(
MPMarshalledData *data, ...) {
va_list nodes;
va_start( nodes, data );
MPMarshalledData *child = mpw_marshal_data_vget( data, nodes );
va_end( nodes );
return child;
}
const MPMarshalledData *mpw_marshal_data_vfind(
const MPMarshalledData *data, va_list nodes) {
const MPMarshalledData *parent = data, *child;
for (const char *node; parent && (node = va_arg( nodes, const char * )); parent = child) {
child = NULL;
for (size_t c = 0; c < parent->children_count; ++c) {
const char *key = parent->children[c].key;
if (key && strcmp( node, key ) == OK) {
child = &parent->children[c];
break;
}
}
if (!child)
break;
}
return parent;
}
const MPMarshalledData *mpw_marshal_data_find(
const MPMarshalledData *data, ...) {
va_list nodes;
va_start( nodes, data );
const MPMarshalledData *child = mpw_marshal_data_vfind( data, nodes );
va_end( nodes );
return child;
}
bool mpw_marshal_data_vis_null(
const MPMarshalledData *data, va_list nodes) {
const MPMarshalledData *child = mpw_marshal_data_vfind( data, nodes );
return !child || child->is_null;
}
bool mpw_marshal_data_is_null(
const MPMarshalledData *data, ...) {
va_list nodes;
va_start( nodes, data );
bool value = mpw_marshal_data_vis_null( data, nodes );
va_end( nodes );
return value;
}
bool mpw_marshal_data_vset_null(
MPMarshalledData *data, va_list nodes) {
MPMarshalledData *child = mpw_marshal_data_vget( data, nodes );
if (!child)
return false;
mpw_free_string( &child->str_value );
for (unsigned int c = 0; c < child->children_count; ++c) {
mpw_marshal_data_set_null( &child->children[c], NULL );
mpw_free_string( &child->children[c].key );
}
mpw_free( &child->children, sizeof( MPMarshalledData ) * child->children_count );
child->children_count = 0;
child->num_value = NAN;
child->is_bool = false;
child->is_null = true;
return true; return true;
}
bool success = true; bool mpw_marshal_data_set_null(
MPMarshalledData *data, ...) {
success &= mpw_marshal_info_free( &(*file)->info ); va_list nodes;
success &= mpw_marshal_user_free( &(*file)->user ); va_start( nodes, data );
success &= mpw_marshal_data_null( (*file)->data ); bool success = mpw_marshal_data_vset_null( data, nodes );
success &= mpw_free( &(*file)->data, sizeof( MPMarshalledData ) ); va_end( nodes );
success &= mpw_free( file, sizeof( MPMarshalledFile ) );
return success;
}
bool mpw_marshal_data_vget_bool(
const MPMarshalledData *data, va_list nodes) {
const MPMarshalledData *child = mpw_marshal_data_vfind( data, nodes );
return child && child->is_bool && child->num_value != false;
}
bool mpw_marshal_data_get_bool(
const MPMarshalledData *data, ...) {
va_list nodes;
va_start( nodes, data );
bool value = mpw_marshal_data_vget_bool( data, nodes );
va_end( nodes );
return value;
}
bool mpw_marshal_data_vset_bool(
const bool value, MPMarshalledData *data, va_list nodes) {
MPMarshalledData *child = mpw_marshal_data_vget( data, nodes );
if (!child || !mpw_marshal_data_set_null( child, NULL ))
return false;
child->is_null = false;
child->is_bool = true;
child->num_value = value != false;
return true;
}
bool mpw_marshal_data_set_bool(
const bool value, MPMarshalledData *data, ...) {
va_list nodes;
va_start( nodes, data );
bool success = mpw_marshal_data_vset_bool( value, data, nodes );
va_end( nodes );
return success;
}
double mpw_marshal_data_vget_num(
const MPMarshalledData *data, va_list nodes) {
const MPMarshalledData *child = mpw_marshal_data_vfind( data, nodes );
return child == NULL? NAN: child->num_value;
}
double mpw_marshal_data_get_num(
const MPMarshalledData *data, ...) {
va_list nodes;
va_start( nodes, data );
double value = mpw_marshal_data_vget_num( data, nodes );
va_end( nodes );
return value;
}
bool mpw_marshal_data_vset_num(
const double value, MPMarshalledData *data, va_list nodes) {
MPMarshalledData *child = mpw_marshal_data_vget( data, nodes );
if (!child || !mpw_marshal_data_set_null( child, NULL ))
return false;
child->is_null = false;
child->num_value = value;
child->str_value = mpw_strdup( mpw_str( "%g", value ) );
return true;
}
bool mpw_marshal_data_set_num(
const double value, MPMarshalledData *data, ...) {
va_list nodes;
va_start( nodes, data );
bool success = mpw_marshal_data_vset_num( value, data, nodes );
va_end( nodes );
return success;
}
const char *mpw_marshal_data_vget_str(
const MPMarshalledData *data, va_list nodes) {
const MPMarshalledData *child = mpw_marshal_data_vfind( data, nodes );
return child == NULL? NULL: mpw_strdup( child->str_value );
}
const char *mpw_marshal_data_get_str(
const MPMarshalledData *data, ...) {
va_list nodes;
va_start( nodes, data );
const char *value = mpw_marshal_data_vget_str( data, nodes );
va_end( nodes );
return value;
}
bool mpw_marshal_data_vset_str(
const char *value, MPMarshalledData *data, va_list nodes) {
MPMarshalledData *child = mpw_marshal_data_vget( data, nodes );
if (!child || !mpw_marshal_data_set_null( child, NULL ))
return false;
if (value) {
child->is_null = false;
child->str_value = mpw_strdup( value );
}
return true;
}
bool mpw_marshal_data_set_str(
const char *value, MPMarshalledData *data, ...) {
va_list nodes;
va_start( nodes, data );
bool success = mpw_marshal_data_vset_str( value, data, nodes );
va_end( nodes );
return success; return success;
} }
@ -285,20 +519,24 @@ static const char *mpw_marshal_write_flat(
#if MPW_JSON #if MPW_JSON
static json_object *mpw_get_json_data( static json_object *mpw_get_json_data(
MPMarshalledData *data) { const MPMarshalledData *data) {
if (!data || data->is_null) if (!data || data->is_null)
return NULL; return NULL;
if (data->is_bool) if (data->is_bool)
return json_object_new_boolean( data->num_value != false ); return json_object_new_boolean( data->num_value != false );
if (!isnan( data->num_value )) if (!isnan( data->num_value )) {
if (data->str_value)
return json_object_new_double_s( data->num_value, data->str_value ); return json_object_new_double_s( data->num_value, data->str_value );
else
return json_object_new_double( data->num_value );
}
if (data->str_value) if (data->str_value)
return json_object_new_string( data->str_value ); return json_object_new_string( data->str_value );
json_object *obj = NULL; json_object *obj = NULL;
for (size_t index = 0; index < data->children_count; ++index) { for (size_t c = 0; c < data->children_count; ++c) {
MPMarshalledData *child = &data->children[index]; MPMarshalledData *child = &data->children[c];
if (!obj) { if (!obj) {
if (child->key) if (child->key)
obj = json_object_new_object(); obj = json_object_new_object();
@ -505,8 +743,8 @@ static void mpw_marshal_read_flat_info(
break; break;
// Header // Header
char *headerName = mpw_get_token( &positionInLine, endOfLine, ":\n" ); const char *headerName = mpw_get_token( &positionInLine, endOfLine, ":\n" );
char *headerValue = mpw_get_token( &positionInLine, endOfLine, "\n" ); const char *headerValue = mpw_get_token( &positionInLine, endOfLine, "\n" );
if (!headerName || !headerValue) if (!headerName || !headerValue)
continue; continue;
@ -605,8 +843,8 @@ static MPMarshalledFile *mpw_marshal_read_flat(
} }
// Header // Header
char *headerName = mpw_get_token( &positionInLine, endOfLine, ":\n" ); const char *headerName = mpw_get_token( &positionInLine, endOfLine, ":\n" );
char *headerValue = mpw_get_token( &positionInLine, endOfLine, "\n" ); const char *headerValue = mpw_get_token( &positionInLine, endOfLine, "\n" );
if (!headerName || !headerValue) { if (!headerName || !headerValue) {
error->type = MPMarshalErrorStructure; error->type = MPMarshalErrorStructure;
error->message = mpw_str( "Invalid header: %s", mpw_strndup( positionInLine, (size_t)(endOfLine - positionInLine) ) ); error->message = mpw_str( "Invalid header: %s", mpw_strndup( positionInLine, (size_t)(endOfLine - positionInLine) ) );
@ -672,8 +910,8 @@ static MPMarshalledFile *mpw_marshal_read_flat(
continue; continue;
// Site // Site
char *siteName = NULL, *siteResultState = NULL, *siteLoginState = NULL; const char *siteName = NULL, *siteResultState = NULL, *siteLoginState = NULL;
char *str_lastUsed = NULL, *str_uses = NULL, *str_type = NULL, *str_algorithm = NULL, *str_counter = NULL; const char *str_lastUsed = NULL, *str_uses = NULL, *str_type = NULL, *str_algorithm = NULL, *str_counter = NULL;
switch (format) { switch (format) {
case 0: { case 0: {
str_lastUsed = mpw_get_token( &positionInLine, endOfLine, " \t\n" ); str_lastUsed = mpw_get_token( &positionInLine, endOfLine, " \t\n" );
@ -834,6 +1072,9 @@ static MPMarshalledFile *mpw_marshal_read_flat(
static void mpw_set_json_data( static void mpw_set_json_data(
MPMarshalledData *data, json_object *obj) { MPMarshalledData *data, json_object *obj) {
if (!data)
return;
json_type type = json_object_get_type( obj ); json_type type = json_object_get_type( obj );
data->is_null = type == json_type_null; data->is_null = type == json_type_null;
data->is_bool = type == json_type_boolean; data->is_bool = type == json_type_boolean;
@ -860,16 +1101,15 @@ static void mpw_set_json_data(
size_t newChildrenCount = 0; size_t newChildrenCount = 0;
for (size_t c = 0; c < data->children_count; ++c) { for (size_t c = 0; c < data->children_count; ++c) {
MPMarshalledData *child = &data->children[c]; MPMarshalledData *child = &data->children[c];
if ((type != json_type_object && type != json_type_array) || if ((type != json_type_object && type != json_type_array) || (child->key && type != json_type_object)) {
(child->key && type != json_type_object) || (!isnan( child->index ) && type != json_type_array)) { // Not a valid child in this object, remove it.
mpw_marshal_data_null( child ); mpw_marshal_data_set_null( child, NULL );
if (!newChildren) { mpw_free_string( &child->key );
newChildren = malloc( sizeof( MPMarshalledData ) * newChildrenCount ); if (!newChildren)
if (newChildren) newChildren = mpw_memdup( data->children, sizeof( MPMarshalledData ) * newChildrenCount );
memcpy( newChildren, data->children, sizeof( MPMarshalledData ) * newChildrenCount );
}
} }
else { else {
// Valid child in this object, keep it.
++newChildrenCount; ++newChildrenCount;
if (newChildren) { if (newChildren) {
if (!mpw_realloc( &newChildren, NULL, sizeof( MPMarshalledData ) * newChildrenCount )) { if (!mpw_realloc( &newChildren, NULL, sizeof( MPMarshalledData ) * newChildrenCount )) {
@ -896,7 +1136,7 @@ static void mpw_set_json_data(
// Find existing child. // Find existing child.
for (size_t c = 0; c < data->children_count; ++c) for (size_t c = 0; c < data->children_count; ++c)
if (data->children[c].key == entry.key || if (data->children[c].key == entry.key ||
(data->children[c].key && entry.key && strcmp( data->children[c].key, entry.key )) == OK) { (data->children[c].key && entry.key && strcmp( data->children[c].key, entry.key ) == OK)) {
child = &data->children[c]; child = &data->children[c];
break; break;
} }
@ -965,7 +1205,7 @@ static void mpw_marshal_read_json_info(
} }
static MPMarshalledFile *mpw_marshal_read_json( static MPMarshalledFile *mpw_marshal_read_json(
const char *in, MPMasterKeyProvider masterKeyProvider, MPMarshalError *error) { const char *in, const MPMasterKeyProvider masterKeyProvider, MPMarshalError *error) {
*error = (MPMarshalError){ MPMarshalErrorInternal, "Unexpected internal error." }; *error = (MPMarshalError){ MPMarshalErrorInternal, "Unexpected internal error." };
if (!in || !strlen( in )) { if (!in || !strlen( in )) {
@ -1173,11 +1413,8 @@ static MPMarshalledFile *mpw_marshal_read_json(
} }
mpw_free( &masterKey, MPMasterKeySize ); mpw_free( &masterKey, MPMasterKeySize );
MPMarshalledData *data = malloc( sizeof( MPMarshalledData ) ); MPMarshalledData *data = mpw_marshal_data_new();
if (data) {
*data = (MPMarshalledData){};
mpw_set_json_data( data, json_file ); mpw_set_json_data( data, json_file );
}
json_object_put( json_file ); json_object_put( json_file );
MPMarshalledFile *file = mpw_marshal_file( user, data ); MPMarshalledFile *file = mpw_marshal_file( user, data );
@ -1223,7 +1460,7 @@ MPMarshalInfo *mpw_marshal_read_info(
} }
MPMarshalledFile *mpw_marshal_read( MPMarshalledFile *mpw_marshal_read(
const char *in, MPMasterKeyProvider masterKeyProvider, MPMarshalError *error) { const char *in, const MPMasterKeyProvider masterKeyProvider, MPMarshalError *error) {
MPMarshalInfo *info = mpw_marshal_read_info( in ); MPMarshalInfo *info = mpw_marshal_read_info( in );
if (!info) if (!info)
@ -1314,10 +1551,10 @@ const char **mpw_marshal_format_extensions(
return NULL; return NULL;
case MPMarshalFormatFlat: case MPMarshalFormatFlat:
return mpw_strings( count, return mpw_strings( count,
mpw_marshal_format_extension( format ), "mpsites.txt", "txt" ); mpw_marshal_format_extension( format ), "mpsites.txt", "txt", NULL );
case MPMarshalFormatJSON: case MPMarshalFormatJSON:
return mpw_strings( count, return mpw_strings( count,
mpw_marshal_format_extension( format ), "mpsites.json", "json" ); mpw_marshal_format_extension( format ), "mpsites.json", "json", NULL );
default: { default: {
dbg( "Unknown format: %d", format ); dbg( "Unknown format: %d", format );
return NULL; return NULL;

View File

@ -23,6 +23,7 @@
MP_LIBS_BEGIN MP_LIBS_BEGIN
#include <time.h> #include <time.h>
#include <stdarg.h>
MP_LIBS_END MP_LIBS_END
//// Types. //// Types.
@ -161,14 +162,14 @@ MPMarshalInfo *mpw_marshal_read_info(
/** Unmarshall sites in the given input buffer by parsing it using the given marshalling format. /** Unmarshall sites in the given input buffer by parsing it using the given marshalling format.
* @return A user object (allocated), or NULL if the format provides no marshalling or a format error occurred. */ * @return A user object (allocated), or NULL if the format provides no marshalling or a format error occurred. */
MPMarshalledFile *mpw_marshal_read( MPMarshalledFile *mpw_marshal_read(
const char *in, MPMasterKeyProvider masterKeyProvider, MPMarshalError *error); const char *in, const MPMasterKeyProvider masterKeyProvider, MPMarshalError *error);
//// Utilities. //// Creating.
/** Create a new user object ready for marshalling. /** Create a new user object ready for marshalling.
* @return A user object (allocated), or NULL if the fullName is missing or the marshalled user couldn't be allocated. */ * @return A user object (allocated), or NULL if the fullName is missing or the marshalled user couldn't be allocated. */
MPMarshalledUser *mpw_marshal_user( MPMarshalledUser *mpw_marshal_user(
const char *fullName, MPMasterKeyProvider masterKeyProvider, const MPAlgorithmVersion algorithmVersion); const char *fullName, const MPMasterKeyProvider masterKeyProvider, const MPAlgorithmVersion algorithmVersion);
/** Create a new site attached to the given user object, ready for marshalling. /** Create a new site attached to the given user object, ready for marshalling.
* @return A site object (allocated), or NULL if the siteName is missing or the marshalled site couldn't be allocated. */ * @return A site object (allocated), or NULL if the siteName is missing or the marshalled site couldn't be allocated. */
MPMarshalledSite *mpw_marshal_site( MPMarshalledSite *mpw_marshal_site(
@ -183,11 +184,77 @@ MPMarshalledQuestion *mpw_marshal_question(
MPMarshalledFile *mpw_marshal_file( MPMarshalledFile *mpw_marshal_file(
MPMarshalledUser *user, MPMarshalledData *data); MPMarshalledUser *user, MPMarshalledData *data);
//// Disposing.
/** Free the given user object and all associated data. */ /** Free the given user object and all associated data. */
bool mpw_marshal_info_free( void mpw_marshal_info_free(
MPMarshalInfo **info); MPMarshalInfo **info);
bool mpw_marshal_free( void mpw_marshal_user_free(
MPMarshalledFile **user); MPMarshalledUser **user);
void mpw_marshal_file_free(
MPMarshalledFile **file);
//// Exploring.
/** Create a null value.
* @return A new data value (allocated), initialized to a null value, or NULL if the value couldn't be allocated. */
MPMarshalledData *mpw_marshal_data_new(void);
/** Get or create a value for the given path in the data store.
* @return The value at this path (shared), or NULL if the value didn't exist and couldn't be created. */
MPMarshalledData *mpw_marshal_data_get(
MPMarshalledData *data, ...);
MPMarshalledData *mpw_marshal_data_vget(
MPMarshalledData *data, va_list nodes);
/** Look up the value at the given path in the data store.
* @return The value at this path (shared), or NULL if there is no value at this path. */
const MPMarshalledData *mpw_marshal_data_find(
const MPMarshalledData *data, ...);
const MPMarshalledData *mpw_marshal_data_vfind(
const MPMarshalledData *data, va_list nodes);
/** Check if the data represents a NULL value.
* @return true if the value at this path is null or is missing, false if it is a non-null type. */
bool mpw_marshal_data_is_null(
const MPMarshalledData *data, ...);
bool mpw_marshal_data_vis_null(
const MPMarshalledData *data, va_list nodes);
/** Set a null value at the given path in the data store.
* @return true if the object was successfully modified. */
bool mpw_marshal_data_set_null(
MPMarshalledData *data, ...);
bool mpw_marshal_data_vset_null(
MPMarshalledData *data, va_list nodes);
/** Look up the boolean value at the given path in the data store.
* @return true if the value at this path is true, false if it is not or there is no boolean value at this path. */
bool mpw_marshal_data_get_bool(
const MPMarshalledData *data, ...);
bool mpw_marshal_data_vget_bool(
const MPMarshalledData *data, va_list nodes);
/** Set a boolean value at the given path in the data store.
* @return true if the object was successfully modified. */
bool mpw_marshal_data_set_bool(
const bool value, MPMarshalledData *data, ...);
bool mpw_marshal_data_vset_bool(
const bool value, MPMarshalledData *data, va_list nodes);
/** Look up the numeric value at the given path in the data store.
* @return A number or NAN if there is no numeric value at this path. */
double mpw_marshal_data_get_num(
const MPMarshalledData *data, ...);
double mpw_marshal_data_vget_num(
const MPMarshalledData *data, va_list nodes);
bool mpw_marshal_data_set_num(
const double value, MPMarshalledData *data, ...);
bool mpw_marshal_data_vset_num(
const double value, MPMarshalledData *data, va_list nodes);
/** Look up the string value at the given path in the data store.
* @return The string value (allocated) or string representation of the number at this path; NULL if there is no such value at this path. */
const char *mpw_marshal_data_get_str(
const MPMarshalledData *data, ...);
const char *mpw_marshal_data_vget_str(
const MPMarshalledData *data, va_list nodes);
bool mpw_marshal_data_set_str(
const char *value, MPMarshalledData *data, ...);
bool mpw_marshal_data_vset_str(
const char *value, MPMarshalledData *data, va_list nodes);
//// Format. //// Format.

View File

@ -90,7 +90,7 @@ const MPResultType mpw_type_named(const char *typeName) {
return (MPResultType)ERR; return (MPResultType)ERR;
} }
const char *mpw_type_abbreviation(MPResultType resultType) { const char *mpw_type_abbreviation(const MPResultType resultType) {
switch (resultType) { switch (resultType) {
case MPResultTypeTemplateMaximum: case MPResultTypeTemplateMaximum:
@ -122,7 +122,7 @@ const char *mpw_type_abbreviation(MPResultType resultType) {
} }
} }
const char *mpw_type_short_name(MPResultType resultType) { const char *mpw_type_short_name(const MPResultType resultType) {
switch (resultType) { switch (resultType) {
case MPResultTypeTemplateMaximum: case MPResultTypeTemplateMaximum:
@ -154,7 +154,7 @@ const char *mpw_type_short_name(MPResultType resultType) {
} }
} }
const char *mpw_type_long_name(MPResultType resultType) { const char *mpw_type_long_name(const MPResultType resultType) {
switch (resultType) { switch (resultType) {
case MPResultTypeTemplateMaximum: case MPResultTypeTemplateMaximum:
@ -186,7 +186,7 @@ const char *mpw_type_long_name(MPResultType resultType) {
} }
} }
const char **mpw_type_templates(MPResultType type, size_t *count) { const char **mpw_type_templates(const MPResultType type, size_t *count) {
if (!(type & MPResultTypeClassTemplate)) { if (!(type & MPResultTypeClassTemplate)) {
dbg( "Not a generated type: %d", type ); dbg( "Not a generated type: %d", type );
@ -231,7 +231,7 @@ const char **mpw_type_templates(MPResultType type, size_t *count) {
} }
} }
const char *mpw_type_template(MPResultType type, uint8_t templateIndex) { const char *mpw_type_template(const MPResultType type, const uint8_t templateIndex) {
size_t count = 0; size_t count = 0;
const char **templates = mpw_type_templates( type, &count ); const char **templates = mpw_type_templates( type, &count );
@ -254,7 +254,7 @@ const MPKeyPurpose mpw_purpose_named(const char *purposeName) {
return (MPKeyPurpose)ERR; return (MPKeyPurpose)ERR;
} }
const char *mpw_purpose_name(MPKeyPurpose purpose) { const char *mpw_purpose_name(const MPKeyPurpose purpose) {
switch (purpose) { switch (purpose) {
case MPKeyPurposeAuthentication: case MPKeyPurposeAuthentication:
@ -270,7 +270,7 @@ const char *mpw_purpose_name(MPKeyPurpose purpose) {
} }
} }
const char *mpw_purpose_scope(MPKeyPurpose purpose) { const char *mpw_purpose_scope(const MPKeyPurpose purpose) {
switch (purpose) { switch (purpose) {
case MPKeyPurposeAuthentication: case MPKeyPurposeAuthentication:
@ -286,7 +286,7 @@ const char *mpw_purpose_scope(MPKeyPurpose purpose) {
} }
} }
const char *mpw_class_characters(char characterClass) { const char *mpw_class_characters(const char characterClass) {
switch (characterClass) { switch (characterClass) {
case 'V': case 'V':
@ -316,7 +316,7 @@ const char *mpw_class_characters(char characterClass) {
} }
} }
const char mpw_class_character(char characterClass, uint8_t seedByte) { const char mpw_class_character(const char characterClass, const uint8_t seedByte) {
const char *classCharacters = mpw_class_characters( characterClass ); const char *classCharacters = mpw_class_characters( characterClass );
if (!classCharacters || !strlen( classCharacters )) if (!classCharacters || !strlen( classCharacters ))

View File

@ -152,11 +152,11 @@ const MPKeyPurpose mpw_purpose_named(const char *purposeName);
/** /**
* @return The standard name (static) for the given purpose or NULL if the purpose is not known. * @return The standard name (static) for the given purpose or NULL if the purpose is not known.
*/ */
const char *mpw_purpose_name(MPKeyPurpose purpose); const char *mpw_purpose_name(const MPKeyPurpose purpose);
/** /**
* @return The scope identifier (static) to apply when encoding for the given purpose or NULL if the purpose is not known. * @return The scope identifier (static) to apply when encoding for the given purpose or NULL if the purpose is not known.
*/ */
const char *mpw_purpose_scope(MPKeyPurpose purpose); const char *mpw_purpose_scope(const MPKeyPurpose purpose);
/** /**
* @return The password type represented by the given name or ERR if the name does not represent a known type. * @return The password type represented by the given name or ERR if the name does not represent a known type.
@ -165,34 +165,34 @@ const MPResultType mpw_type_named(const char *typeName);
/** /**
* @return The standard identifying name (static) for the given password type or NULL if the type is not known. * @return The standard identifying name (static) for the given password type or NULL if the type is not known.
*/ */
const char *mpw_type_abbreviation(MPResultType resultType); const char *mpw_type_abbreviation(const MPResultType resultType);
/** /**
* @return The standard identifying name (static) for the given password type or NULL if the type is not known. * @return The standard identifying name (static) for the given password type or NULL if the type is not known.
*/ */
const char *mpw_type_short_name(MPResultType resultType); const char *mpw_type_short_name(const MPResultType resultType);
/** /**
* @return The descriptive name (static) for the given password type or NULL if the type is not known. * @return The descriptive name (static) for the given password type or NULL if the type is not known.
*/ */
const char *mpw_type_long_name(MPResultType resultType); const char *mpw_type_long_name(const MPResultType resultType);
/** /**
* @return An array (allocated, count) of strings (static) that express the templates to use for the given type. * @return An array (allocated, count) of strings (static) that express the templates to use for the given type.
* NULL if the type is not known or is not a MPResultTypeClassTemplate. * NULL if the type is not known or is not a MPResultTypeClassTemplate.
*/ */
const char **mpw_type_templates(MPResultType type, size_t *count); const char **mpw_type_templates(const MPResultType type, size_t *count);
/** /**
* @return A string (static) that contains the password encoding template of the given type for a seed that starts with the given byte. * @return A string (static) that contains the password encoding template of the given type for a seed that starts with the given byte.
* NULL if the type is not known or is not a MPResultTypeClassTemplate. * NULL if the type is not known or is not a MPResultTypeClassTemplate.
*/ */
const char *mpw_type_template(MPResultType type, uint8_t templateIndex); const char *mpw_type_template(const MPResultType type, const uint8_t templateIndex);
/** /**
* @return An string (static) with all the characters in the given character class or NULL if the character class is not known. * @return An string (static) with all the characters in the given character class or NULL if the character class is not known.
*/ */
const char *mpw_class_characters(char characterClass); const char *mpw_class_characters(const char characterClass);
/** /**
* @return A character from given character class that encodes the given byte or NUL if the character class is not known or is empty. * @return A character from given character class that encodes the given byte or NUL if the character class is not known or is empty.
*/ */
const char mpw_class_character(char characterClass, uint8_t seedByte); const char mpw_class_character(const char characterClass, const uint8_t seedByte);
#endif // _MPW_TYPES_H #endif // _MPW_TYPES_H

View File

@ -175,7 +175,7 @@ bool __mpw_free(void **buffer, const size_t bufferSize) {
bool __mpw_free_string(char **string) { bool __mpw_free_string(char **string) {
return *string && __mpw_free( (void **)string, strlen( *string ) ); return string && *string && __mpw_free( (void **)string, strlen( *string ) );
} }
bool __mpw_free_strings(char **strings, ...) { bool __mpw_free_strings(char **strings, ...) {
@ -193,7 +193,7 @@ bool __mpw_free_strings(char **strings, ...) {
} }
uint8_t const *mpw_kdf_scrypt(const size_t keySize, const uint8_t *secret, const size_t secretSize, const uint8_t *salt, const size_t saltSize, uint8_t const *mpw_kdf_scrypt(const size_t keySize, const uint8_t *secret, const size_t secretSize, const uint8_t *salt, const size_t saltSize,
uint64_t N, uint32_t r, uint32_t p) { const uint64_t N, const uint32_t r, const uint32_t p) {
if (!secret || !salt || !secretSize || !saltSize) if (!secret || !salt || !secretSize || !saltSize)
return NULL; return NULL;
@ -367,7 +367,7 @@ const char *mpw_hotp(const uint8_t *key, size_t keySize, uint64_t movingFactor,
} }
#endif #endif
MPKeyID mpw_id_buf(const void *buf, size_t length) { const MPKeyID mpw_id_buf(const void *buf, const size_t length) {
if (!buf) if (!buf)
return NULL; return NULL;
@ -443,7 +443,7 @@ const char *mpw_vstr(const char *format, va_list args) {
return str_str[str_str_i]; return str_str[str_str_i];
} }
const char *mpw_hex(const void *buf, size_t length) { const char *mpw_hex(const void *buf, const size_t length) {
if (!buf || !length) if (!buf || !length)
return NULL; return NULL;
@ -461,7 +461,7 @@ const char *mpw_hex(const void *buf, size_t length) {
return mpw_hex_buf[mpw_hex_buf_i]; return mpw_hex_buf[mpw_hex_buf_i];
} }
const char *mpw_hex_l(uint32_t number) { const char *mpw_hex_l(const uint32_t number) {
uint8_t buf[4 /* 32 / 8 */]; uint8_t buf[4 /* 32 / 8 */];
buf[0] = (uint8_t)((number >> 24) & UINT8_MAX); buf[0] = (uint8_t)((number >> 24) & UINT8_MAX);
@ -496,7 +496,7 @@ size_t mpw_utf8_strchars(const char *utf8String) {
return strchars; return strchars;
} }
void *mpw_memdup(const void *src, size_t len) { void *mpw_memdup(const void *src, const size_t len) {
if (!src) if (!src)
return NULL; return NULL;
@ -517,7 +517,7 @@ char *mpw_strdup(const char *src) {
return mpw_memdup( src, len + 1 ); return mpw_memdup( src, len + 1 );
} }
char *mpw_strndup(const char *src, size_t max) { char *mpw_strndup(const char *src, const size_t max) {
if (!src) if (!src)
return NULL; return NULL;
@ -525,8 +525,7 @@ char *mpw_strndup(const char *src, size_t max) {
size_t len = 0; size_t len = 0;
for (; len < max && src[len] != '\0'; ++len); for (; len < max && src[len] != '\0'; ++len);
char *dst = malloc( len + 1 ); char *dst = mpw_memdup( src, len + 1 );
memcpy( dst, src, len );
dst[len] = '\0'; dst[len] = '\0';
return dst; return dst;

View File

@ -122,7 +122,7 @@ bool mpw_string_push(
bool mpw_string_pushf( bool mpw_string_pushf(
char **string, const char *pushFormat, ...); char **string, const char *pushFormat, ...);
// These defines merely exist to force the void** cast (& do type-checking), since void** casts are not automatic. // These defines merely exist to do type-checking, force the void** cast & drop any const qualifier.
/** Reallocate the given buffer from the given size by adding the delta size. /** Reallocate the given buffer from the given size by adding the delta size.
* On success, the buffer size pointer will be updated to the buffer's new size * On success, the buffer size pointer will be updated to the buffer's new size
* and the buffer pointer may be updated to a new memory address. * and the buffer pointer may be updated to a new memory address.
@ -176,7 +176,7 @@ bool __mpw_free_string(
bool __mpw_free_strings( bool __mpw_free_strings(
char **strings, ...); char **strings, ...);
void mpw_zero( void mpw_zero(
void *buffer, size_t bufferSize); void *buffer, const size_t bufferSize);
//// Cryptographic functions. //// Cryptographic functions.
@ -184,7 +184,7 @@ void mpw_zero(
* @return A buffer (allocated, keySize) containing the key or NULL if secret or salt is missing, key could not be allocated or the KDF failed. */ * @return A buffer (allocated, keySize) containing the key or NULL if secret or salt is missing, key could not be allocated or the KDF failed. */
uint8_t const *mpw_kdf_scrypt( uint8_t const *mpw_kdf_scrypt(
const size_t keySize, const uint8_t *secret, const size_t secretSize, const uint8_t *salt, const size_t saltSize, const size_t keySize, const uint8_t *secret, const size_t secretSize, const uint8_t *salt, const size_t saltSize,
uint64_t N, uint32_t r, uint32_t p); const uint64_t N, const uint32_t r, const uint32_t p);
/** Derive a subkey from the given key using the blake2b KDF. /** Derive a subkey from the given key using the blake2b KDF.
* @return A buffer (allocated, keySize) containing the key or NULL if the key or subkeySize is missing, the key sizes are out of bounds, the subkey could not be allocated or derived. */ * @return A buffer (allocated, keySize) containing the key or NULL if the key or subkeySize is missing, the key sizes are out of bounds, the subkey could not be allocated or derived. */
uint8_t const *mpw_kdf_blake2b( uint8_t const *mpw_kdf_blake2b(
@ -217,11 +217,11 @@ const char *mpw_str(const char *format, ...);
const char *mpw_vstr(const char *format, va_list args); const char *mpw_vstr(const char *format, va_list args);
/** Encode a buffer as a string of hexadecimal characters. /** Encode a buffer as a string of hexadecimal characters.
* @return A string (shared); or NULL if the buffer is missing or the result could not be allocated. */ * @return A string (shared); or NULL if the buffer is missing or the result could not be allocated. */
const char *mpw_hex(const void *buf, size_t length); const char *mpw_hex(const void *buf, const size_t length);
const char *mpw_hex_l(uint32_t number); const char *mpw_hex_l(const uint32_t number);
/** Encode a fingerprint for a buffer. /** Encode a fingerprint for a buffer.
* @return A string (shared); or NULL if the buffer is missing or the result could not be allocated. */ * @return A string (shared); or NULL if the buffer is missing or the result could not be allocated. */
MPKeyID mpw_id_buf(const void *buf, size_t length); const MPKeyID mpw_id_buf(const void *buf, const size_t length);
/** Compare two fingerprints for equality. /** Compare two fingerprints for equality.
* @return true if the buffers represent identical fingerprints or are both NULL. */ * @return true if the buffers represent identical fingerprints or are both NULL. */
bool mpw_id_buf_equals(const char *id1, const char *id2); bool mpw_id_buf_equals(const char *id1, const char *id2);
@ -234,14 +234,14 @@ size_t mpw_utf8_charlen(const char *utf8String);
size_t mpw_utf8_strchars(const char *utf8String); size_t mpw_utf8_strchars(const char *utf8String);
/** Drop-in for memdup(3). /** Drop-in for memdup(3).
* @return A buffer (allocated, len) with len bytes copied from src or NULL if src is missing or the buffer could not be allocated. */ * @return A buffer (allocated, len) with len bytes copied from src or NULL if src is missing or the buffer could not be allocated. */
void *mpw_memdup(const void *src, size_t len); void *mpw_memdup(const void *src, const size_t len);
/** Drop-in for POSIX strdup(3). /** Drop-in for POSIX strdup(3).
* @return A string (allocated) copied from src or NULL if src is missing or the buffer could not be allocated. */ * @return A string (allocated) copied from src or NULL if src is missing or the buffer could not be allocated. */
char *mpw_strdup(const char *src); char *mpw_strdup(const char *src);
/** Drop-in for POSIX strndup(3). /** Drop-in for POSIX strndup(3).
* @return A string (allocated) with no more than max bytes copied from src or NULL if src is missing or the buffer could not be allocated. */ * @return A string (allocated) with no more than max bytes copied from src or NULL if src is missing or the buffer could not be allocated. */
char *mpw_strndup(const char *src, size_t max); char *mpw_strndup(const char *src, const size_t max);
/** Drop-in for POSIX strncasecmp(3). */ /** Drop-in for POSIX strncasecmp(3). */
int mpw_strncasecmp(const char *s1, const char *s2, size_t max); int mpw_strncasecmp(const char *s1, const char *s2, const size_t max);
#endif // _MPW_UTIL_H #endif // _MPW_UTIL_H