2
0

Rename identifiers to align better with their meaning (siteVariant -> keyPurpose, siteContext -> keyContext, siteType -> passwordType).

This commit is contained in:
Maarten Billemont 2017-08-01 13:45:54 -04:00
parent 3c5cb1673a
commit 9d5105a9e5
16 changed files with 351 additions and 350 deletions

View File

@ -44,20 +44,20 @@ MPMasterKey mpw_masterKey(const char *fullName, const char *masterPassword, cons
MPSiteKey mpw_siteKey(
MPMasterKey masterKey, const char *siteName, const uint32_t siteCounter,
const MPSiteVariant siteVariant, const char *siteContext, const MPAlgorithmVersion algorithmVersion) {
const MPKeyPurpose keyPurpose, const char *keyContext, const MPAlgorithmVersion algorithmVersion) {
if (!masterKey || !siteName)
return NULL;
switch (algorithmVersion) {
case MPAlgorithmVersion0:
return mpw_siteKey_v0( masterKey, siteName, siteCounter, siteVariant, siteContext );
return mpw_siteKey_v0( masterKey, siteName, siteCounter, keyPurpose, keyContext );
case MPAlgorithmVersion1:
return mpw_siteKey_v1( masterKey, siteName, siteCounter, siteVariant, siteContext );
return mpw_siteKey_v1( masterKey, siteName, siteCounter, keyPurpose, keyContext );
case MPAlgorithmVersion2:
return mpw_siteKey_v2( masterKey, siteName, siteCounter, siteVariant, siteContext );
return mpw_siteKey_v2( masterKey, siteName, siteCounter, keyPurpose, keyContext );
case MPAlgorithmVersion3:
return mpw_siteKey_v3( masterKey, siteName, siteCounter, siteVariant, siteContext );
return mpw_siteKey_v3( masterKey, siteName, siteCounter, keyPurpose, keyContext );
default:
ftl( "Unsupported version: %d", algorithmVersion );
return NULL;
@ -65,20 +65,20 @@ MPSiteKey mpw_siteKey(
}
const char *mpw_sitePassword(
MPSiteKey siteKey, const MPSiteType siteType, const MPAlgorithmVersion algorithmVersion) {
MPSiteKey siteKey, const MPPasswordType passwordType, const MPAlgorithmVersion algorithmVersion) {
if (!siteKey)
return NULL;
switch (algorithmVersion) {
case MPAlgorithmVersion0:
return mpw_sitePassword_v0( siteKey, siteType );
return mpw_sitePassword_v0( siteKey, passwordType );
case MPAlgorithmVersion1:
return mpw_sitePassword_v1( siteKey, siteType );
return mpw_sitePassword_v1( siteKey, passwordType );
case MPAlgorithmVersion2:
return mpw_sitePassword_v2( siteKey, siteType );
return mpw_sitePassword_v2( siteKey, passwordType );
case MPAlgorithmVersion3:
return mpw_sitePassword_v3( siteKey, siteType );
return mpw_sitePassword_v3( siteKey, passwordType );
default:
ftl( "Unsupported version: %d", algorithmVersion );
return NULL;

View File

@ -46,11 +46,11 @@ MPMasterKey mpw_masterKey(
* @return A new MPSiteKeySize-byte allocated buffer or NULL if an error occurred. */
MPSiteKey mpw_siteKey(
MPMasterKey masterKey, const char *siteName, const uint32_t siteCounter,
const MPSiteVariant siteVariant, const char *siteContext, const MPAlgorithmVersion algorithmVersion);
const MPKeyPurpose keyPurpose, const char *keyContext, const MPAlgorithmVersion algorithmVersion);
/** Encode a password for the site from the given site key.
* @return A newly allocated string or NULL if an error occurred. */
const char *mpw_sitePassword(
MPSiteKey siteKey, const MPSiteType siteType, const MPAlgorithmVersion algorithmVersion);
MPSiteKey siteKey, const MPPasswordType passwordType, const MPAlgorithmVersion algorithmVersion);
#endif // _MPW_ALGORITHM_H

View File

@ -28,7 +28,7 @@
#define MP_p 2
#define MP_hash PearlHashSHA256
static const char *mpw_templateForType_v0(MPSiteType type, uint16_t seedByte) {
static const char *mpw_templateForType_v0(MPPasswordType type, uint16_t seedByte) {
size_t count = 0;
const char **templates = mpw_templatesForType( type, &count );
@ -45,7 +45,7 @@ static const char mpw_characterFromClass_v0(char characterClass, uint16_t seedBy
static MPMasterKey mpw_masterKeyForUser_v0(const char *fullName, const char *masterPassword) {
const char *mpKeyScope = mpw_scopeForVariant( MPSiteVariantPassword );
const char *mpKeyScope = mpw_scopeForPurpose( MPKeyPurposeAuthentication );
trc( "algorithm: v%d\n", 0 );
trc( "fullName: %s (%zu)\n", fullName, mpw_utf8_strlen( fullName ) );
trc( "masterPassword: %s\n", masterPassword );
@ -79,59 +79,60 @@ static MPMasterKey mpw_masterKeyForUser_v0(const char *fullName, const char *mas
static MPSiteKey mpw_siteKey_v0(
MPMasterKey masterKey, const char *siteName, const uint32_t siteCounter,
const MPSiteVariant siteVariant, const char *siteContext) {
const MPKeyPurpose keyPurpose, const char *keyContext) {
const char *siteScope = mpw_scopeForVariant( siteVariant );
const char *keyScope = mpw_scopeForPurpose( keyPurpose );
trc( "-- mpw_siteKey_v0\n" );
trc( "siteName: %s\n", siteName );
trc( "siteCounter: %d\n", siteCounter );
trc( "siteVariant: %d\n", siteVariant );
trc( "site scope: %s, context: %s\n", siteScope, siteContext? "<empty>": siteContext );
trc( "seed from: hmac-sha256(masterKey, %s | %s | %s | %s | %s | %s)\n",
siteScope, mpw_hex_l( htonl( strlen( siteName ) ) ), siteName,
trc( "keyPurpose: %d\n", keyPurpose );
trc( "keyScope: %s, keyContext: %s\n", keyScope, keyContext? "<empty>": keyContext );
trc( "siteKey: hmac-sha256(masterKey, %s | %s | %s | %s | %s | %s)\n",
keyScope, mpw_hex_l( htonl( strlen( siteName ) ) ), siteName,
mpw_hex_l( htonl( siteCounter ) ),
mpw_hex_l( htonl( siteContext? strlen( siteContext ): 0 ) ), siteContext? "(null)": siteContext );
mpw_hex_l( htonl( keyContext? strlen( keyContext ): 0 ) ), keyContext? "(null)": keyContext );
// Calculate the site seed.
// siteKey = hmac-sha256( masterKey, siteScope . #siteName . siteName . siteCounter . #siteContext . siteContext )
size_t sitePasswordInfoSize = 0;
uint8_t *sitePasswordInfo = NULL;
mpw_push_string( &sitePasswordInfo, &sitePasswordInfoSize, siteScope );
mpw_push_int( &sitePasswordInfo, &sitePasswordInfoSize, htonl( mpw_utf8_strlen( siteName ) ) );
mpw_push_string( &sitePasswordInfo, &sitePasswordInfoSize, siteName );
mpw_push_int( &sitePasswordInfo, &sitePasswordInfoSize, htonl( siteCounter ) );
if (siteContext) {
mpw_push_int( &sitePasswordInfo, &sitePasswordInfoSize, htonl( mpw_utf8_strlen( siteContext ) ) );
mpw_push_string( &sitePasswordInfo, &sitePasswordInfoSize, siteContext );
// siteKey = hmac-sha256( masterKey, keyScope . #siteName . siteName . siteCounter . #keyContext . keyContext )
size_t siteSaltSize = 0;
uint8_t *siteSalt = NULL;
mpw_push_string( &siteSalt, &siteSaltSize, keyScope );
mpw_push_int( &siteSalt, &siteSaltSize, htonl( mpw_utf8_strlen( siteName ) ) );
mpw_push_string( &siteSalt, &siteSaltSize, siteName );
mpw_push_int( &siteSalt, &siteSaltSize, htonl( siteCounter ) );
if (keyContext) {
mpw_push_int( &siteSalt, &siteSaltSize, htonl( mpw_utf8_strlen( keyContext ) ) );
mpw_push_string( &siteSalt, &siteSaltSize, keyContext );
}
if (!sitePasswordInfo) {
ftl( "Could not allocate site seed info: %d\n", errno );
if (!siteSalt || !siteSaltSize) {
ftl( "Could not allocate site salt: %d\n", errno );
mpw_free( siteSalt, siteSaltSize );
return NULL;
}
trc( "sitePasswordInfo ID: %s\n", mpw_id_buf( sitePasswordInfo, sitePasswordInfoSize ) );
trc( "siteSalt ID: %s\n", mpw_id_buf( siteSalt, siteSaltSize ) );
MPSiteKey siteKey = mpw_hmac_sha256( masterKey, MPMasterKeySize, sitePasswordInfo, sitePasswordInfoSize );
mpw_free( sitePasswordInfo, sitePasswordInfoSize );
MPSiteKey siteKey = mpw_hmac_sha256( masterKey, MPMasterKeySize, siteSalt, siteSaltSize );
mpw_free( siteSalt, siteSaltSize );
if (!siteKey) {
ftl( "Could not allocate site seed: %d\n", errno );
ftl( "Could not allocate site key: %d\n", errno );
return NULL;
}
trc( "siteKey ID: %s\n", mpw_id_buf( siteKey, 32 ) );
trc( "siteKey ID: %s\n", mpw_id_buf( siteKey, MPSiteKeySize ) );
return siteKey;
}
static const char *mpw_sitePassword_v0(
MPSiteKey siteKey, const MPSiteType siteType) {
MPSiteKey siteKey, const MPPasswordType passwordType) {
trc( "-- mpw_sitePassword_v0\n" );
trc( "siteType: %d\n", siteType );
trc( "passwordType: %d\n", passwordType );
// Determine the template.
const char *_siteKey = (const char *)siteKey;
const char *template = mpw_templateForType_v0( siteType, htons( _siteKey[0] ) );
trc( "type %d, template: %s\n", siteType, template );
if (strlen( template ) > 32) {
const char *template = mpw_templateForType_v0( passwordType, htons( _siteKey[0] ) );
trc( "type %d, template: %s\n", passwordType, template );
if (strlen( template ) > MPSiteKeySize) {
ftl( "Template too long for password seed: %lu", strlen( template ) );
mpw_free( _siteKey, sizeof( _siteKey ) );
return NULL;

View File

@ -29,7 +29,7 @@
static MPMasterKey mpw_masterKeyForUser_v1(const char *fullName, const char *masterPassword) {
const char *mpKeyScope = mpw_scopeForVariant( MPSiteVariantPassword );
const char *mpKeyScope = mpw_scopeForPurpose( MPKeyPurposeAuthentication );
trc( "algorithm: v%d\n", 1 );
trc( "fullName: %s (%zu)\n", fullName, mpw_utf8_strlen( fullName ) );
trc( "masterPassword: %s\n", masterPassword );
@ -63,58 +63,59 @@ static MPMasterKey mpw_masterKeyForUser_v1(const char *fullName, const char *mas
static MPSiteKey mpw_siteKey_v1(
MPMasterKey masterKey, const char *siteName, const uint32_t siteCounter,
const MPSiteVariant siteVariant, const char *siteContext) {
const MPKeyPurpose keyPurpose, const char *keyContext) {
const char *siteScope = mpw_scopeForVariant( siteVariant );
const char *keyScope = mpw_scopeForPurpose( keyPurpose );
trc( "-- mpw_siteKey_v1\n" );
trc( "siteName: %s\n", siteName );
trc( "siteCounter: %d\n", siteCounter );
trc( "siteVariant: %d\n", siteVariant );
trc( "site scope: %s, context: %s\n", siteScope, siteContext? "<empty>": siteContext );
trc( "seed from: hmac-sha256(masterKey, %s | %s | %s | %s | %s | %s)\n",
siteScope, mpw_hex_l( htonl( strlen( siteName ) ) ), siteName,
trc( "keyPurpose: %d\n", keyPurpose );
trc( "keyScope: %s, keyContext: %s\n", keyScope, keyContext? "<empty>": keyContext );
trc( "siteKey: hmac-sha256(masterKey, %s | %s | %s | %s | %s | %s)\n",
keyScope, mpw_hex_l( htonl( strlen( siteName ) ) ), siteName,
mpw_hex_l( htonl( siteCounter ) ),
mpw_hex_l( htonl( siteContext? strlen( siteContext ): 0 ) ), siteContext? "(null)": siteContext );
mpw_hex_l( htonl( keyContext? strlen( keyContext ): 0 ) ), keyContext? "(null)": keyContext );
// Calculate the site seed.
// siteKey = hmac-sha256( masterKey, siteScope . #siteName . siteName . siteCounter . #siteContext . siteContext )
size_t sitePasswordInfoSize = 0;
uint8_t *sitePasswordInfo = NULL;
mpw_push_string( &sitePasswordInfo, &sitePasswordInfoSize, siteScope );
mpw_push_int( &sitePasswordInfo, &sitePasswordInfoSize, htonl( mpw_utf8_strlen( siteName ) ) );
mpw_push_string( &sitePasswordInfo, &sitePasswordInfoSize, siteName );
mpw_push_int( &sitePasswordInfo, &sitePasswordInfoSize, htonl( siteCounter ) );
if (siteContext) {
mpw_push_int( &sitePasswordInfo, &sitePasswordInfoSize, htonl( mpw_utf8_strlen( siteContext ) ) );
mpw_push_string( &sitePasswordInfo, &sitePasswordInfoSize, siteContext );
// siteKey = hmac-sha256( masterKey, keyScope . #siteName . siteName . siteCounter . #keyContext . keyContext )
size_t siteSaltSize = 0;
uint8_t *siteSalt = NULL;
mpw_push_string( &siteSalt, &siteSaltSize, keyScope );
mpw_push_int( &siteSalt, &siteSaltSize, htonl( mpw_utf8_strlen( siteName ) ) );
mpw_push_string( &siteSalt, &siteSaltSize, siteName );
mpw_push_int( &siteSalt, &siteSaltSize, htonl( siteCounter ) );
if (keyContext) {
mpw_push_int( &siteSalt, &siteSaltSize, htonl( mpw_utf8_strlen( keyContext ) ) );
mpw_push_string( &siteSalt, &siteSaltSize, keyContext );
}
if (!sitePasswordInfo) {
ftl( "Could not allocate site seed info: %d\n", errno );
if (!siteSalt || !siteSaltSize) {
ftl( "Could not allocate site salt: %d\n", errno );
mpw_free( siteSalt, siteSaltSize );
return NULL;
}
trc( "sitePasswordInfo ID: %s\n", mpw_id_buf( sitePasswordInfo, sitePasswordInfoSize ) );
trc( "siteSalt ID: %s\n", mpw_id_buf( siteSalt, siteSaltSize ) );
MPSiteKey siteKey = mpw_hmac_sha256( masterKey, MPMasterKeySize, sitePasswordInfo, sitePasswordInfoSize );
mpw_free( sitePasswordInfo, sitePasswordInfoSize );
MPSiteKey siteKey = mpw_hmac_sha256( masterKey, MPMasterKeySize, siteSalt, siteSaltSize );
mpw_free( siteSalt, siteSaltSize );
if (!siteKey) {
ftl( "Could not allocate site seed: %d\n", errno );
ftl( "Could not allocate site key: %d\n", errno );
return NULL;
}
trc( "siteKey ID: %s\n", mpw_id_buf( siteKey, 32 ) );
trc( "siteKey ID: %s\n", mpw_id_buf( siteKey, MPSiteKeySize ) );
return siteKey;
}
static const char *mpw_sitePassword_v1(
MPSiteKey siteKey, const MPSiteType siteType) {
MPSiteKey siteKey, const MPPasswordType passwordType) {
trc( "-- mpw_sitePassword_v1\n" );
trc( "siteType: %d\n", siteType );
trc( "passwordType: %d\n", passwordType );
// Determine the template.
const char *template = mpw_templateForType( siteType, siteKey[0] );
trc( "type %d, template: %s\n", siteType, template );
if (strlen( template ) > 32) {
const char *template = mpw_templateForType( passwordType, siteKey[0] );
trc( "type %d, template: %s\n", passwordType, template );
if (strlen( template ) > MPSiteKeySize) {
ftl( "Template too long for password seed: %lu", strlen( template ) );
mpw_free( siteKey, sizeof( siteKey ) );
return NULL;

View File

@ -29,7 +29,7 @@
static MPMasterKey mpw_masterKeyForUser_v2(const char *fullName, const char *masterPassword) {
const char *mpKeyScope = mpw_scopeForVariant( MPSiteVariantPassword );
const char *mpKeyScope = mpw_scopeForPurpose( MPKeyPurposeAuthentication );
trc( "algorithm: v%d\n", 2 );
trc( "fullName: %s (%zu)\n", fullName, mpw_utf8_strlen( fullName ) );
trc( "masterPassword: %s\n", masterPassword );
@ -63,58 +63,59 @@ static MPMasterKey mpw_masterKeyForUser_v2(const char *fullName, const char *mas
static MPSiteKey mpw_siteKey_v2(
MPMasterKey masterKey, const char *siteName, const uint32_t siteCounter,
const MPSiteVariant siteVariant, const char *siteContext) {
const MPKeyPurpose keyPurpose, const char *keyContext) {
const char *siteScope = mpw_scopeForVariant( siteVariant );
const char *keyScope = mpw_scopeForPurpose( keyPurpose );
trc( "-- mpw_siteKey_v2\n" );
trc( "siteName: %s\n", siteName );
trc( "siteCounter: %d\n", siteCounter );
trc( "siteVariant: %d\n", siteVariant );
trc( "site scope: %s, context: %s\n", siteScope, siteContext? "<empty>": siteContext );
trc( "seed from: hmac-sha256(masterKey, %s | %s | %s | %s | %s | %s)\n",
siteScope, mpw_hex_l( htonl( strlen( siteName ) ) ), siteName,
trc( "keyPurpose: %d\n", keyPurpose );
trc( "keyScope: %s, keyContext: %s\n", keyScope, keyContext? "<empty>": keyContext );
trc( "siteKey: hmac-sha256(masterKey, %s | %s | %s | %s | %s | %s)\n",
keyScope, mpw_hex_l( htonl( strlen( siteName ) ) ), siteName,
mpw_hex_l( htonl( siteCounter ) ),
mpw_hex_l( htonl( siteContext? strlen( siteContext ): 0 ) ), siteContext? "(null)": siteContext );
mpw_hex_l( htonl( keyContext? strlen( keyContext ): 0 ) ), keyContext? "(null)": keyContext );
// Calculate the site seed.
// siteKey = hmac-sha256( masterKey, siteScope . #siteName . siteName . siteCounter . #siteContext . siteContext )
size_t sitePasswordInfoSize = 0;
uint8_t *sitePasswordInfo = NULL;
mpw_push_string( &sitePasswordInfo, &sitePasswordInfoSize, siteScope );
mpw_push_int( &sitePasswordInfo, &sitePasswordInfoSize, htonl( strlen( siteName ) ) );
mpw_push_string( &sitePasswordInfo, &sitePasswordInfoSize, siteName );
mpw_push_int( &sitePasswordInfo, &sitePasswordInfoSize, htonl( siteCounter ) );
if (siteContext) {
mpw_push_int( &sitePasswordInfo, &sitePasswordInfoSize, htonl( strlen( siteContext ) ) );
mpw_push_string( &sitePasswordInfo, &sitePasswordInfoSize, siteContext );
// siteKey = hmac-sha256( masterKey, keyScope . #siteName . siteName . siteCounter . #keyContext . keyContext )
size_t siteSaltSize = 0;
uint8_t *siteSalt = NULL;
mpw_push_string( &siteSalt, &siteSaltSize, keyScope );
mpw_push_int( &siteSalt, &siteSaltSize, htonl( strlen( siteName ) ) );
mpw_push_string( &siteSalt, &siteSaltSize, siteName );
mpw_push_int( &siteSalt, &siteSaltSize, htonl( siteCounter ) );
if (keyContext) {
mpw_push_int( &siteSalt, &siteSaltSize, htonl( strlen( keyContext ) ) );
mpw_push_string( &siteSalt, &siteSaltSize, keyContext );
}
if (!sitePasswordInfo) {
ftl( "Could not allocate site seed info: %d\n", errno );
if (!siteSalt || !siteSaltSize) {
ftl( "Could not allocate site salt: %d\n", errno );
mpw_free( siteSalt, siteSaltSize );
return NULL;
}
trc( "sitePasswordInfo ID: %s\n", mpw_id_buf( sitePasswordInfo, sitePasswordInfoSize ) );
trc( "siteSalt ID: %s\n", mpw_id_buf( siteSalt, siteSaltSize ) );
const uint8_t *siteKey = mpw_hmac_sha256( masterKey, MPMasterKeySize, sitePasswordInfo, sitePasswordInfoSize );
mpw_free( sitePasswordInfo, sitePasswordInfoSize );
const uint8_t *siteKey = mpw_hmac_sha256( masterKey, MPMasterKeySize, siteSalt, siteSaltSize );
mpw_free( siteSalt, siteSaltSize );
if (!siteKey) {
ftl( "Could not allocate site seed: %d\n", errno );
ftl( "Could not allocate site key: %d\n", errno );
return NULL;
}
trc( "siteKey ID: %s\n", mpw_id_buf( siteKey, 32 ) );
trc( "siteKey ID: %s\n", mpw_id_buf( siteKey, MPSiteKeySize ) );
return siteKey;
}
static const char *mpw_sitePassword_v2(
MPSiteKey siteKey, const MPSiteType siteType) {
MPSiteKey siteKey, const MPPasswordType passwordType) {
trc( "-- mpw_sitePassword_v2\n" );
trc( "siteType: %d\n", siteType );
trc( "passwordType: %d\n", passwordType );
// Determine the template.
const char *template = mpw_templateForType( siteType, siteKey[0] );
trc( "type %d, template: %s\n", siteType, template );
if (strlen( template ) > 32) {
const char *template = mpw_templateForType( passwordType, siteKey[0] );
trc( "type %d, template: %s\n", passwordType, template );
if (strlen( template ) > MPSiteKeySize) {
ftl( "Template too long for password seed: %lu", strlen( template ) );
mpw_free( siteKey, sizeof( siteKey ) );
return NULL;

View File

@ -29,7 +29,7 @@
static MPMasterKey mpw_masterKeyForUser_v3(const char *fullName, const char *masterPassword) {
const char *mpKeyScope = mpw_scopeForVariant( MPSiteVariantPassword );
const char *mpKeyScope = mpw_scopeForPurpose( MPKeyPurposeAuthentication );
trc( "-- mpw_masterKeyForUser_v3\n" );
trc( "fullName: %s (%zu)\n", fullName, strlen( fullName ) );
trc( "masterPassword: %s\n", masterPassword );
@ -63,58 +63,59 @@ static MPMasterKey mpw_masterKeyForUser_v3(const char *fullName, const char *mas
static MPSiteKey mpw_siteKey_v3(
MPMasterKey masterKey, const char *siteName, const uint32_t siteCounter,
const MPSiteVariant siteVariant, const char *siteContext) {
const MPKeyPurpose keyPurpose, const char *keyContext) {
const char *siteScope = mpw_scopeForVariant( siteVariant );
const char *keyScope = mpw_scopeForPurpose( keyPurpose );
trc( "-- mpw_siteKey_v3\n" );
trc( "siteName: %s\n", siteName );
trc( "siteCounter: %d\n", siteCounter );
trc( "siteVariant: %d\n", siteVariant );
trc( "site scope: %s, context: %s\n", siteScope, siteContext? "<empty>": siteContext );
trc( "seed from: hmac-sha256(masterKey, %s | %s | %s | %s | %s | %s)\n",
siteScope, mpw_hex_l( htonl( strlen( siteName ) ) ), siteName,
trc( "keyPurpose: %d\n", keyPurpose );
trc( "keyScope: %s, keyContext: %s\n", keyScope, keyContext? "<empty>": keyContext );
trc( "siteKey: hmac-sha256(masterKey, %s | %s | %s | %s | %s | %s)\n",
keyScope, mpw_hex_l( htonl( strlen( siteName ) ) ), siteName,
mpw_hex_l( htonl( siteCounter ) ),
mpw_hex_l( htonl( siteContext? strlen( siteContext ): 0 ) ), siteContext? "(null)": siteContext );
mpw_hex_l( htonl( keyContext? strlen( keyContext ): 0 ) ), keyContext? "(null)": keyContext );
// Calculate the site seed.
// siteKey = hmac-sha256( masterKey, siteScope . #siteName . siteName . siteCounter . #siteContext . siteContext )
size_t sitePasswordInfoSize = 0;
uint8_t *sitePasswordInfo = NULL;
mpw_push_string( &sitePasswordInfo, &sitePasswordInfoSize, siteScope );
mpw_push_int( &sitePasswordInfo, &sitePasswordInfoSize, htonl( strlen( siteName ) ) );
mpw_push_string( &sitePasswordInfo, &sitePasswordInfoSize, siteName );
mpw_push_int( &sitePasswordInfo, &sitePasswordInfoSize, htonl( siteCounter ) );
if (siteContext) {
mpw_push_int( &sitePasswordInfo, &sitePasswordInfoSize, htonl( strlen( siteContext ) ) );
mpw_push_string( &sitePasswordInfo, &sitePasswordInfoSize, siteContext );
// siteKey = hmac-sha256( masterKey, keyScope . #siteName . siteName . siteCounter . #keyContext . keyContext )
size_t siteSaltSize = 0;
uint8_t *siteSalt = NULL;
mpw_push_string( &siteSalt, &siteSaltSize, keyScope );
mpw_push_int( &siteSalt, &siteSaltSize, htonl( strlen( siteName ) ) );
mpw_push_string( &siteSalt, &siteSaltSize, siteName );
mpw_push_int( &siteSalt, &siteSaltSize, htonl( siteCounter ) );
if (keyContext) {
mpw_push_int( &siteSalt, &siteSaltSize, htonl( strlen( keyContext ) ) );
mpw_push_string( &siteSalt, &siteSaltSize, keyContext );
}
if (!sitePasswordInfo) {
ftl( "Could not allocate site seed info: %d\n", errno );
if (!siteSalt) {
ftl( "Could not allocate site salt: %d\n", errno );
return NULL;
}
trc( "sitePasswordInfo ID: %s\n", mpw_id_buf( sitePasswordInfo, sitePasswordInfoSize ) );
trc( "siteSalt ID: %s\n", mpw_id_buf( siteSalt, siteSaltSize ) );
MPSiteKey siteKey = mpw_hmac_sha256( masterKey, MPMasterKeySize, sitePasswordInfo, sitePasswordInfoSize );
mpw_free( sitePasswordInfo, sitePasswordInfoSize );
if (!siteKey) {
ftl( "Could not allocate site seed: %d\n", errno );
MPSiteKey siteKey = mpw_hmac_sha256( masterKey, MPMasterKeySize, siteSalt, siteSaltSize );
mpw_free( siteSalt, siteSaltSize );
if (!siteKey || !siteSaltSize) {
ftl( "Could not allocate site key: %d\n", errno );
mpw_free( siteSalt, siteSaltSize );
return NULL;
}
trc( "siteKey ID: %s\n", mpw_id_buf( siteKey, 32 ) );
trc( "siteKey ID: %s\n", mpw_id_buf( siteKey, MPSiteKeySize ) );
return siteKey;
}
static const char *mpw_sitePassword_v3(
MPSiteKey siteKey, const MPSiteType siteType) {
MPSiteKey siteKey, const MPPasswordType passwordType) {
trc( "-- mpw_sitePassword_v3\n" );
trc( "siteType: %d\n", siteType );
trc( "passwordType: %d\n", passwordType );
// Determine the template.
const char *template = mpw_templateForType( siteType, siteKey[0] );
trc( "type %d, template: %s\n", siteType, template );
if (strlen( template ) > 32) {
const char *template = mpw_templateForType( passwordType, siteKey[0] );
trc( "type %d, template: %s\n", passwordType, template );
if (strlen( template ) > MPSiteKeySize) {
ftl( "Template too long for password seed: %lu", strlen( template ) );
mpw_free( siteKey, sizeof( siteKey ) );
return NULL;

View File

@ -38,7 +38,7 @@ MPMarshalledUser *mpw_marshall_user(
.redacted = true,
.avatar = 0,
.defaultType = MPSiteTypeDefault,
.defaultType = MPPasswordTypeDefault,
.lastUsed = 0,
.sites_count = 0,
@ -49,7 +49,7 @@ MPMarshalledUser *mpw_marshall_user(
MPMarshalledSite *mpw_marshall_site(
MPMarshalledUser *marshalledUser,
const char *siteName, const MPSiteType siteType, const uint32_t siteCounter, const MPAlgorithmVersion algorithmVersion) {
const char *siteName, const MPPasswordType siteType, const uint32_t siteCounter, const MPAlgorithmVersion algorithmVersion) {
if (!siteName || !(marshalledUser->sites =
realloc( marshalledUser->sites, sizeof( MPMarshalledSite ) * (++marshalledUser->sites_count) )))
@ -170,8 +170,8 @@ static bool mpw_marshall_write_flat(
return false;
}
if (site.type & MPSiteTypeClassGenerated) {
MPSiteKey siteKey = mpw_siteKey( masterKey, site.name, site.counter, MPSiteVariantPassword, NULL, site.algorithm );
if (site.type & MPPasswordTypeClassGenerated) {
MPSiteKey siteKey = mpw_siteKey( masterKey, site.name, site.counter, MPKeyPurposeAuthentication, NULL, site.algorithm );
content = mpw_sitePassword( siteKey, site.type, site.algorithm );
mpw_free( siteKey, MPSiteKeySize );
}
@ -253,8 +253,8 @@ static bool mpw_marshall_write_json(
return false;
}
if (site.type & MPSiteTypeClassGenerated) {
MPSiteKey siteKey = mpw_siteKey( masterKey, site.name, site.counter, MPSiteVariantPassword, NULL, site.algorithm );
if (site.type & MPPasswordTypeClassGenerated) {
MPSiteKey siteKey = mpw_siteKey( masterKey, site.name, site.counter, MPKeyPurposeAuthentication, NULL, site.algorithm );
content = mpw_sitePassword( siteKey, site.type, site.algorithm );
mpw_free( siteKey, MPSiteKeySize );
}
@ -290,8 +290,8 @@ static bool mpw_marshall_write_json(
json_object_object_add( json_site_questions, question.keyword, json_site_question );
if (!user->redacted) {
MPSiteKey siteKey = mpw_siteKey( masterKey, site.name, 1, MPSiteVariantAnswer, question.keyword, site.algorithm );
const char *answer = mpw_sitePassword( siteKey, MPSiteTypeGeneratedPhrase, site.algorithm );
MPSiteKey siteKey = mpw_siteKey( masterKey, site.name, 1, MPKeyPurposeRecovery, question.keyword, site.algorithm );
const char *answer = mpw_sitePassword( siteKey, MPPasswordTypeGeneratedPhrase, site.algorithm );
mpw_free( siteKey, MPSiteKeySize );
if (answer)
json_object_object_add( json_site_question, "answer", json_object_new_string( answer ) );
@ -338,7 +338,7 @@ static MPMarshalledUser *mpw_marshall_read_flat(
unsigned int importFormat = 0, importAvatar = 0;
char *importUserName = NULL, *importKeyID = NULL, *importDate = NULL;
MPAlgorithmVersion importAlgorithm = MPAlgorithmVersionCurrent, masterKeyAlgorithm = (MPAlgorithmVersion)-1;
MPSiteType importDefaultType = MPSiteTypeDefault;
MPPasswordType importDefaultType = MPPasswordTypeDefault;
bool headerStarted = false, headerEnded = false, importRedacted = false;
for (char *endOfLine, *positionInLine = in; (endOfLine = strstr( positionInLine, "\n" )); positionInLine = endOfLine + 1) {
@ -391,7 +391,7 @@ static MPMarshalledUser *mpw_marshall_read_flat(
importAlgorithm = (MPAlgorithmVersion)importAlgorithmInt;
}
if (strcmp( headerName, "Default Type" ) == 0)
importDefaultType = (MPSiteType)atoi( headerValue );
importDefaultType = (MPPasswordType)atoi( headerValue );
if (strcmp( headerName, "Passwords" ) == 0)
importRedacted = strcmp( headerValue, "VISIBLE" ) != 0;
@ -479,7 +479,7 @@ static MPMarshalledUser *mpw_marshall_read_flat(
}
MPMarshalledSite *site = mpw_marshall_site( user, siteName,
(MPSiteType)atoi( siteType ), (uint32_t)atoi( siteCounter ), siteAlgorithmInt );
(MPPasswordType)atoi( siteType ), (uint32_t)atoi( siteCounter ), siteAlgorithmInt );
if (!site) {
err( "Couldn't allocate a new site.\n" );
return NULL;
@ -565,7 +565,7 @@ static MPMarshalledUser *mpw_marshall_read_json(
*error = MPMarshallErrorIllegal;
return NULL;
}
MPSiteType defaultType = (MPSiteType)mpw_get_json_int( json_file, "user.default_type", MPSiteTypeDefault );
MPPasswordType defaultType = (MPPasswordType)mpw_get_json_int( json_file, "user.default_type", MPPasswordTypeDefault );
if (!fullName || !strlen( fullName )) {
err( "Missing value for full name.\n" );
@ -595,7 +595,7 @@ static MPMarshalledUser *mpw_marshall_read_json(
json_object_iter json_site;
json_object *json_sites = mpw_get_json_section( json_file, "sites" );
json_object_object_foreachC( json_sites, json_site ) {
MPSiteType siteType = (MPSiteType)mpw_get_json_int( json_site.val, "type", (int)user->defaultType );
MPPasswordType siteType = (MPPasswordType)mpw_get_json_int( json_site.val, "type", (int)user->defaultType );
uint32_t siteCounter = (uint32_t)mpw_get_json_int( json_site.val, "counter", 1 );
MPAlgorithmVersion siteAlgorithm = (MPAlgorithmVersion)mpw_get_json_int( json_site.val, "algorithm", (int)user->algorithm );
if (siteAlgorithm < MPAlgorithmVersionFirst || siteAlgorithm > MPAlgorithmVersionLast) {

View File

@ -56,7 +56,7 @@ typedef struct MPMarshalledQuestion {
typedef struct MPMarshalledSite {
const char *name;
const char *content;
MPSiteType type;
MPPasswordType type;
uint32_t counter;
MPAlgorithmVersion algorithm;
@ -78,7 +78,7 @@ typedef struct MPMarshalledUser {
bool redacted;
unsigned int avatar;
MPSiteType defaultType;
MPPasswordType defaultType;
time_t lastUsed;
size_t sites_count;
@ -101,7 +101,7 @@ MPMarshalledUser *mpw_marshall_user(
const char *fullName, const char *masterPassword, const MPAlgorithmVersion algorithmVersion);
MPMarshalledSite *mpw_marshall_site(
MPMarshalledUser *marshalledUser,
const char *siteName, const MPSiteType siteType, const uint32_t siteCounter, const MPAlgorithmVersion algorithmVersion);
const char *siteName, const MPPasswordType siteType, const uint32_t siteCounter, const MPAlgorithmVersion algorithmVersion);
MPMarshalledQuestion *mpw_marshal_question(
MPMarshalledSite *marshalledSite, const char *keyword);
bool mpw_marshal_free(

View File

@ -29,7 +29,7 @@
#include "mpw-types.h"
#include "mpw-util.h"
const MPSiteType mpw_typeWithName(const char *typeName) {
const MPPasswordType mpw_typeWithName(const char *typeName) {
// Lower-case and trim optionally leading "Generated" string from typeName to standardize it.
size_t stdTypeNameOffset = 0;
@ -41,42 +41,41 @@ const MPSiteType mpw_typeWithName(const char *typeName) {
stdTypeName[c] = (char)tolower( typeName[c + stdTypeNameOffset] );
stdTypeName[stdTypeNameSize] = '\0';
// Find what site type is represented by the type name.
if (0 == strcmp( stdTypeName, "x" ) || 0 == strcmp( stdTypeName, "max" ) || 0 == strcmp( stdTypeName, "maximum" ))
return MPSiteTypeGeneratedMaximum;
if (0 == strcmp( stdTypeName, "l" ) || 0 == strcmp( stdTypeName, "long" ))
return MPSiteTypeGeneratedLong;
if (0 == strcmp( stdTypeName, "m" ) || 0 == strcmp( stdTypeName, "med" ) || 0 == strcmp( stdTypeName, "medium" ))
return MPSiteTypeGeneratedMedium;
if (0 == strcmp( stdTypeName, "b" ) || 0 == strcmp( stdTypeName, "basic" ))
return MPSiteTypeGeneratedBasic;
if (0 == strcmp( stdTypeName, "s" ) || 0 == strcmp( stdTypeName, "short" ))
return MPSiteTypeGeneratedShort;
if (0 == strcmp( stdTypeName, "i" ) || 0 == strcmp( stdTypeName, "pin" ))
return MPSiteTypeGeneratedPIN;
if (0 == strcmp( stdTypeName, "n" ) || 0 == strcmp( stdTypeName, "name" ))
return MPSiteTypeGeneratedName;
if (0 == strcmp( stdTypeName, "p" ) || 0 == strcmp( stdTypeName, "phrase" ))
return MPSiteTypeGeneratedPhrase;
// Find what password type is represented by the type name.
if (0 == strncmp( "maximum", stdTypeName, strlen( stdTypeName ) ) || 0 == strncmp( "x", stdTypeName, 1 ))
return MPPasswordTypeGeneratedMaximum;
if (0 == strncmp( "long", stdTypeName, strlen( stdTypeName ) ) || 0 == strncmp( "l", stdTypeName, 1 ))
return MPPasswordTypeGeneratedLong;
if (0 == strncmp( "medium", stdTypeName, strlen( stdTypeName ) ) || 0 == strncmp( "m", stdTypeName, 1 ))
return MPPasswordTypeGeneratedMedium;
if (0 == strncmp( "basic", stdTypeName, strlen( stdTypeName ) ) || 0 == strncmp( "b", stdTypeName, 1 ))
return MPPasswordTypeGeneratedBasic;
if (0 == strncmp( "short", stdTypeName, strlen( stdTypeName ) ) || 0 == strncmp( "s", stdTypeName, 1 ))
return MPPasswordTypeGeneratedShort;
if (0 == strncmp( "pin", stdTypeName, strlen( stdTypeName ) ) || 0 == strncmp( "i", stdTypeName, 1 ))
return MPPasswordTypeGeneratedPIN;
if (0 == strncmp( "name", stdTypeName, strlen( stdTypeName ) ) || 0 == strncmp( "n", stdTypeName, 1 ))
return MPPasswordTypeGeneratedName;
if (0 == strncmp( "phrase", stdTypeName, strlen( stdTypeName ) ) || 0 == strncmp( "p", stdTypeName, 1 ))
return MPPasswordTypeGeneratedPhrase;
ftl( "Not a generated type name: %s", stdTypeName );
return MPSiteTypeDefault;
return MPPasswordTypeDefault;
}
const char **mpw_templatesForType(MPSiteType type, size_t *count) {
const char **mpw_templatesForType(MPPasswordType type, size_t *count) {
if (!(type & MPSiteTypeClassGenerated)) {
if (!(type & MPPasswordTypeClassGenerated)) {
ftl( "Not a generated type: %d", type );
*count = 0;
return NULL;
}
switch (type) {
case MPSiteTypeGeneratedMaximum: {
case MPPasswordTypeGeneratedMaximum:
return mpw_alloc_array( *count, const char *,
"anoxxxxxxxxxxxxxxxxx", "axxxxxxxxxxxxxxxxxno" );
}
case MPSiteTypeGeneratedLong: {
case MPPasswordTypeGeneratedLong:
return mpw_alloc_array( *count, const char *,
"CvcvnoCvcvCvcv", "CvcvCvcvnoCvcv", "CvcvCvcvCvcvno",
"CvccnoCvcvCvcv", "CvccCvcvnoCvcv", "CvccCvcvCvcvno",
@ -85,31 +84,24 @@ const char **mpw_templatesForType(MPSiteType type, size_t *count) {
"CvccnoCvccCvcv", "CvccCvccnoCvcv", "CvccCvccCvcvno",
"CvcvnoCvccCvcc", "CvcvCvccnoCvcc", "CvcvCvccCvccno",
"CvccnoCvcvCvcc", "CvccCvcvnoCvcc", "CvccCvcvCvccno" );
}
case MPSiteTypeGeneratedMedium: {
case MPPasswordTypeGeneratedMedium:
return mpw_alloc_array( *count, const char *,
"CvcnoCvc", "CvcCvcno" );
}
case MPSiteTypeGeneratedBasic: {
case MPPasswordTypeGeneratedBasic:
return mpw_alloc_array( *count, const char *,
"aaanaaan", "aannaaan", "aaannaaa" );
}
case MPSiteTypeGeneratedShort: {
case MPPasswordTypeGeneratedShort:
return mpw_alloc_array( *count, const char *,
"Cvcn" );
}
case MPSiteTypeGeneratedPIN: {
case MPPasswordTypeGeneratedPIN:
return mpw_alloc_array( *count, const char *,
"nnnn" );
}
case MPSiteTypeGeneratedName: {
case MPPasswordTypeGeneratedName:
return mpw_alloc_array( *count, const char *,
"cvccvcvcv" );
}
case MPSiteTypeGeneratedPhrase: {
case MPPasswordTypeGeneratedPhrase:
return mpw_alloc_array( *count, const char *,
"cvcc cvc cvccvcv cvc", "cvc cvccvcvcv cvcv", "cv cvccv cvc cvcvccv" );
}
default: {
ftl( "Unknown generated type: %d", type );
*count = 0;
@ -118,7 +110,7 @@ const char **mpw_templatesForType(MPSiteType type, size_t *count) {
}
}
const char *mpw_templateForType(MPSiteType type, uint8_t seedByte) {
const char *mpw_templateForType(MPPasswordType type, uint8_t seedByte) {
size_t count = 0;
const char **templates = mpw_templatesForType( type, &count );
@ -127,39 +119,37 @@ const char *mpw_templateForType(MPSiteType type, uint8_t seedByte) {
return template;
}
const MPSiteVariant mpw_variantWithName(const char *variantName) {
const MPKeyPurpose mpw_purposeWithName(const char *purposeName) {
// Lower-case and trim optionally leading "generated" string from typeName to standardize it.
size_t stdVariantNameSize = strlen( variantName );
char stdVariantName[stdVariantNameSize + 1];
for (size_t c = 0; c < stdVariantNameSize; ++c)
stdVariantName[c] = (char)tolower( variantName[c] );
stdVariantName[stdVariantNameSize] = '\0';
size_t stdPurposeNameSize = strlen( purposeName );
char stdPurposeName[stdPurposeNameSize + 1];
for (size_t c = 0; c < stdPurposeNameSize; ++c)
stdPurposeName[c] = (char)tolower( purposeName[c] );
stdPurposeName[stdPurposeNameSize] = '\0';
if (0 == strcmp( stdVariantName, "p" ) || 0 == strcmp( stdVariantName, "password" ))
return MPSiteVariantPassword;
if (0 == strcmp( stdVariantName, "l" ) || 0 == strcmp( stdVariantName, "login" ))
return MPSiteVariantLogin;
if (0 == strcmp( stdVariantName, "a" ) || 0 == strcmp( stdVariantName, "answer" ))
return MPSiteVariantAnswer;
if (strncmp( "authentication", stdPurposeName, strlen( stdPurposeName ) ) == 0)
return MPKeyPurposeAuthentication;
if (strncmp( "identification", stdPurposeName, strlen( stdPurposeName ) ) == 0)
return MPKeyPurposeIdentification;
if (strncmp( "recovery", stdPurposeName, strlen( stdPurposeName ) ) == 0)
return MPKeyPurposeRecovery;
ftl( "Not a variant name: %s", stdVariantName );
ftl( "Not a purpose name: %s", stdPurposeName );
}
const char *mpw_scopeForVariant(MPSiteVariant variant) {
const char *mpw_scopeForPurpose(MPKeyPurpose purpose) {
switch (variant) {
case MPSiteVariantPassword: {
switch (purpose) {
case MPKeyPurposeAuthentication:
return "com.lyndir.masterpassword";
}
case MPSiteVariantLogin: {
case MPKeyPurposeIdentification:
return "com.lyndir.masterpassword.login";
}
case MPSiteVariantAnswer: {
case MPKeyPurposeRecovery:
return "com.lyndir.masterpassword.answer";
}
default: {
ftl( "Unknown variant: %d", variant );
ftl( "Unknown purpose: %d", purpose );
return "";
}
}
}
@ -189,6 +179,7 @@ const char *mpw_charactersInClass(char characterClass) {
return " ";
default: {
ftl( "Unknown character class: %c", characterClass );
return "";
}
}
}

View File

@ -37,20 +37,20 @@ typedef const uint8_t *MPMasterKey;
typedef const uint8_t *MPSiteKey;
typedef const char *MPKeyID;
typedef enum( unsigned int, MPSiteVariant ) {
typedef enum( unsigned int, MPKeyPurpose ) {
/** Generate a key for authentication. */
MPSiteVariantPassword,
MPKeyPurposeAuthentication,
/** Generate a name for identification. */
MPSiteVariantLogin,
/** Generate an answer to a security question. */
MPSiteVariantAnswer,
MPKeyPurposeIdentification,
/** Generate a recovery token. */
MPKeyPurposeRecovery,
};
typedef enum( unsigned int, MPSiteTypeClass ) {
typedef enum( unsigned int, MPPasswordTypeClass ) {
/** Generate the password. */
MPSiteTypeClassGenerated = 1 << 4,
MPPasswordTypeClassGenerated = 1 << 4,
/** Store the password. */
MPSiteTypeClassStored = 1 << 5,
MPPasswordTypeClassStored = 1 << 5,
};
typedef enum( unsigned int, MPSiteFeature ) {
@ -60,37 +60,47 @@ typedef enum( unsigned int, MPSiteFeature ) {
MPSiteFeatureDevicePrivate = 1 << 11,
};
typedef enum( unsigned int, MPSiteType ) {
MPSiteTypeGeneratedMaximum = 0x0 | MPSiteTypeClassGenerated | 0x0,
MPSiteTypeGeneratedLong = 0x1 | MPSiteTypeClassGenerated | 0x0,
MPSiteTypeGeneratedMedium = 0x2 | MPSiteTypeClassGenerated | 0x0,
MPSiteTypeGeneratedBasic = 0x4 | MPSiteTypeClassGenerated | 0x0,
MPSiteTypeGeneratedShort = 0x3 | MPSiteTypeClassGenerated | 0x0,
MPSiteTypeGeneratedPIN = 0x5 | MPSiteTypeClassGenerated | 0x0,
MPSiteTypeGeneratedName = 0xE | MPSiteTypeClassGenerated | 0x0,
MPSiteTypeGeneratedPhrase = 0xF | MPSiteTypeClassGenerated | 0x0,
typedef enum( unsigned int, MPPasswordType ) {
/** pg^VMAUBk5x3p%HP%i4= */
MPPasswordTypeGeneratedMaximum = 0x0 | MPPasswordTypeClassGenerated | 0x0,
/** BiroYena8:Kixa */
MPPasswordTypeGeneratedLong = 0x1 | MPPasswordTypeClassGenerated | 0x0,
/** BirSuj0- */
MPPasswordTypeGeneratedMedium = 0x2 | MPPasswordTypeClassGenerated | 0x0,
/** pO98MoD0 */
MPPasswordTypeGeneratedBasic = 0x4 | MPPasswordTypeClassGenerated | 0x0,
/** Bir8 */
MPPasswordTypeGeneratedShort = 0x3 | MPPasswordTypeClassGenerated | 0x0,
/** 2798 */
MPPasswordTypeGeneratedPIN = 0x5 | MPPasswordTypeClassGenerated | 0x0,
/** birsujano */
MPPasswordTypeGeneratedName = 0xE | MPPasswordTypeClassGenerated | 0x0,
/** bir yennoquce fefi */
MPPasswordTypeGeneratedPhrase = 0xF | MPPasswordTypeClassGenerated | 0x0,
MPSiteTypeStoredPersonal = 0x0 | MPSiteTypeClassStored | MPSiteFeatureExportContent,
MPSiteTypeStoredDevicePrivate = 0x1 | MPSiteTypeClassStored | MPSiteFeatureDevicePrivate,
/** Custom saved password. */
MPPasswordTypeStoredPersonal = 0x0 | MPPasswordTypeClassStored | MPSiteFeatureExportContent,
/** Custom saved password that should not be exported from the device. */
MPPasswordTypeStoredDevicePrivate = 0x1 | MPPasswordTypeClassStored | MPSiteFeatureDevicePrivate,
MPSiteTypeDefault = MPSiteTypeGeneratedLong,
MPPasswordTypeDefault = MPPasswordTypeGeneratedLong,
};
//// Type utilities.
/**
* @return The variant represented by the given name.
* @return The purpose represented by the given name.
*/
const MPSiteVariant mpw_variantWithName(const char *variantName);
const MPKeyPurpose mpw_purposeWithName(const char *purposeName);
/**
* @return An internal string containing the scope identifier to apply when encoding for the given variant.
* @return An internal string containing the scope identifier to apply when encoding for the given purpose.
*/
const char *mpw_scopeForVariant(MPSiteVariant variant);
const char *mpw_scopeForPurpose(MPKeyPurpose purpose);
/**
* @return The type represented by the given name.
*/
const MPSiteType mpw_typeWithName(const char *typeName);
const MPPasswordType mpw_typeWithName(const char *typeName);
/**
* @return A newly allocated array of internal strings that express the templates to use for the given type.
@ -98,12 +108,12 @@ const MPSiteType mpw_typeWithName(const char *typeName);
* If an unsupported type is given, count will be 0 and will return NULL.
* The array needs to be free'ed, the strings themselves must not be free'ed or modified.
*/
const char **mpw_templatesForType(MPSiteType type, size_t *count);
const char **mpw_templatesForType(MPPasswordType type, size_t *count);
/**
* @return An internal string that contains the password encoding template of the given type
* for a seed that starts with the given byte.
*/
const char *mpw_templateForType(MPSiteType type, uint8_t seedByte);
const char *mpw_templateForType(MPPasswordType type, uint8_t seedByte);
/**
* @return An internal string that contains all the characters that occur in the given character class.

View File

@ -288,6 +288,7 @@ static int mpw_utf8_sizeof(unsigned char utf8Byte) {
const size_t mpw_utf8_strlen(const char *utf8String) {
// TODO: is this ever different from strlen?
size_t charlen = 0;
char *remainingString = (char *)utf8String;
for (int charByteSize; (charByteSize = mpw_utf8_sizeof( (unsigned char)*remainingString )); remainingString += charByteSize)

View File

@ -7,8 +7,8 @@
<keyID>98EEF4D1DF46D849574A82A03C3177056B15DFFCA29BB3899DE4628453675302</keyID>
<siteName>masterpasswordapp.com</siteName>
<siteCounter>1</siteCounter>
<siteType>GeneratedLong</siteType>
<siteVariant>Password</siteVariant>
<passwordType>GeneratedLong</passwordType>
<keyPurpose>Password</keyPurpose>
<result><!-- abstract --></result>
</case>
@ -32,45 +32,45 @@
<result>LiheCuwhSerz6)</result>
</case>
<case id="v3_loginName" parent="v3">
<siteVariant>Login</siteVariant>
<siteType>GeneratedName</siteType>
<keyPurpose>Login</keyPurpose>
<passwordType>GeneratedName</passwordType>
<result>wohzaqage</result>
</case>
<case id="v3_securityAnswer" parent="v3">
<siteVariant>Answer</siteVariant>
<siteType>GeneratedPhrase</siteType>
<keyPurpose>Answer</keyPurpose>
<passwordType>GeneratedPhrase</passwordType>
<result>xin diyjiqoja hubu</result>
</case>
<case id="v3_securityAnswer_context" parent="v3_securityAnswer">
<siteContext>question</siteContext>
<keyContext>question</keyContext>
<result>xogx tem cegyiva jab</result>
</case>
<case id="v3_type_maximum" parent="v3">
<siteType>GeneratedMaximum</siteType>
<passwordType>GeneratedMaximum</passwordType>
<result>W6@692^B1#&amp;@gVdSdLZ@</result>
</case>
<case id="v3_type_medium" parent="v3">
<siteType>GeneratedMedium</siteType>
<passwordType>GeneratedMedium</passwordType>
<result>Jej2$Quv</result>
</case>
<case id="v3_type_basic" parent="v3">
<siteType>GeneratedBasic</siteType>
<passwordType>GeneratedBasic</passwordType>
<result>WAo2xIg6</result>
</case>
<case id="v3_type_short" parent="v3">
<siteType>GeneratedShort</siteType>
<passwordType>GeneratedShort</passwordType>
<result>Jej2</result>
</case>
<case id="v3_type_pin" parent="v3">
<siteType>GeneratedPIN</siteType>
<passwordType>GeneratedPIN</passwordType>
<result>7662</result>
</case>
<case id="v3_type_name" parent="v3">
<siteType>GeneratedName</siteType>
<passwordType>GeneratedName</passwordType>
<result>jejraquvo</result>
</case>
<case id="v3_type_phrase" parent="v3">
<siteType>GeneratedPhrase</siteType>
<passwordType>GeneratedPhrase</passwordType>
<result>jejr quv cabsibu tam</result>
</case>
<case id="v3_counter_ceiling" parent="v3">
@ -98,45 +98,45 @@
<result>LiheCuwhSerz6)</result>
</case>
<case id="v2_loginName" parent="v2">
<siteVariant>Login</siteVariant>
<siteType>GeneratedName</siteType>
<keyPurpose>Login</keyPurpose>
<passwordType>GeneratedName</passwordType>
<result>wohzaqage</result>
</case>
<case id="v2_securityAnswer" parent="v2">
<siteVariant>Answer</siteVariant>
<siteType>GeneratedPhrase</siteType>
<keyPurpose>Answer</keyPurpose>
<passwordType>GeneratedPhrase</passwordType>
<result>xin diyjiqoja hubu</result>
</case>
<case id="v2_securityAnswer_context" parent="v2_securityAnswer">
<siteContext>question</siteContext>
<keyContext>question</keyContext>
<result>xogx tem cegyiva jab</result>
</case>
<case id="v2_type_maximum" parent="v2">
<siteType>GeneratedMaximum</siteType>
<passwordType>GeneratedMaximum</passwordType>
<result>W6@692^B1#&amp;@gVdSdLZ@</result>
</case>
<case id="v2_type_medium" parent="v2">
<siteType>GeneratedMedium</siteType>
<passwordType>GeneratedMedium</passwordType>
<result>Jej2$Quv</result>
</case>
<case id="v2_type_basic" parent="v2">
<siteType>GeneratedBasic</siteType>
<passwordType>GeneratedBasic</passwordType>
<result>WAo2xIg6</result>
</case>
<case id="v2_type_short" parent="v2">
<siteType>GeneratedShort</siteType>
<passwordType>GeneratedShort</passwordType>
<result>Jej2</result>
</case>
<case id="v2_type_pin" parent="v2">
<siteType>GeneratedPIN</siteType>
<passwordType>GeneratedPIN</passwordType>
<result>7662</result>
</case>
<case id="v2_type_name" parent="v2">
<siteType>GeneratedName</siteType>
<passwordType>GeneratedName</passwordType>
<result>jejraquvo</result>
</case>
<case id="v2_type_phrase" parent="v2">
<siteType>GeneratedPhrase</siteType>
<passwordType>GeneratedPhrase</passwordType>
<result>jejr quv cabsibu tam</result>
</case>
<case id="v2_counter_ceiling" parent="v2">
@ -164,45 +164,45 @@
<result>WawiYarp2@Kodh</result>
</case>
<case id="v1_loginName" parent="v1">
<siteVariant>Login</siteVariant>
<siteType>GeneratedName</siteType>
<keyPurpose>Login</keyPurpose>
<passwordType>GeneratedName</passwordType>
<result>wohzaqage</result>
</case>
<case id="v1_securityAnswer" parent="v1">
<siteVariant>Answer</siteVariant>
<siteType>GeneratedPhrase</siteType>
<keyPurpose>Answer</keyPurpose>
<passwordType>GeneratedPhrase</passwordType>
<result>xin diyjiqoja hubu</result>
</case>
<case id="v1_securityAnswer_context" parent="v1_securityAnswer">
<siteContext>question</siteContext>
<keyContext>question</keyContext>
<result>xogx tem cegyiva jab</result>
</case>
<case id="v1_type_maximum" parent="v1">
<siteType>GeneratedMaximum</siteType>
<passwordType>GeneratedMaximum</passwordType>
<result>W6@692^B1#&amp;@gVdSdLZ@</result>
</case>
<case id="v1_type_medium" parent="v1">
<siteType>GeneratedMedium</siteType>
<passwordType>GeneratedMedium</passwordType>
<result>Jej2$Quv</result>
</case>
<case id="v1_type_basic" parent="v1">
<siteType>GeneratedBasic</siteType>
<passwordType>GeneratedBasic</passwordType>
<result>WAo2xIg6</result>
</case>
<case id="v1_type_short" parent="v1">
<siteType>GeneratedShort</siteType>
<passwordType>GeneratedShort</passwordType>
<result>Jej2</result>
</case>
<case id="v1_type_pin" parent="v1">
<siteType>GeneratedPIN</siteType>
<passwordType>GeneratedPIN</passwordType>
<result>7662</result>
</case>
<case id="v1_type_name" parent="v1">
<siteType>GeneratedName</siteType>
<passwordType>GeneratedName</passwordType>
<result>jejraquvo</result>
</case>
<case id="v1_type_phrase" parent="v1">
<siteType>GeneratedPhrase</siteType>
<passwordType>GeneratedPhrase</passwordType>
<result>jejr quv cabsibu tam</result>
</case>
<case id="v1_counter_ceiling" parent="v1">
@ -230,45 +230,45 @@
<result>HahiVana2@Nole</result>
</case>
<case id="v0_loginName" parent="v0">
<siteVariant>Login</siteVariant>
<siteType>GeneratedName</siteType>
<keyPurpose>Login</keyPurpose>
<passwordType>GeneratedName</passwordType>
<result>lozwajave</result>
</case>
<case id="v0_securityAnswer" parent="v0">
<siteVariant>Answer</siteVariant>
<siteType>GeneratedPhrase</siteType>
<keyPurpose>Answer</keyPurpose>
<passwordType>GeneratedPhrase</passwordType>
<result>miy lirfijoja dubu</result>
</case>
<case id="v0_securityAnswer_context" parent="v0_securityAnswer">
<siteContext>question</siteContext>
<keyContext>question</keyContext>
<result>movm bex gevrica jaf</result>
</case>
<case id="v0_type_maximum" parent="v0">
<siteType>GeneratedMaximum</siteType>
<passwordType>GeneratedMaximum</passwordType>
<result>w1!3bA3icmRAc)SS@lwl</result>
</case>
<case id="v0_type_medium" parent="v0">
<siteType>GeneratedMedium</siteType>
<passwordType>GeneratedMedium</passwordType>
<result>Fej7]Jug</result>
</case>
<case id="v0_type_basic" parent="v0">
<siteType>GeneratedBasic</siteType>
<passwordType>GeneratedBasic</passwordType>
<result>wvH7irC1</result>
</case>
<case id="v0_type_short" parent="v0">
<siteType>GeneratedShort</siteType>
<passwordType>GeneratedShort</passwordType>
<result>Fej7</result>
</case>
<case id="v0_type_pin" parent="v0">
<siteType>GeneratedPIN</siteType>
<passwordType>GeneratedPIN</passwordType>
<result>2117</result>
</case>
<case id="v0_type_name" parent="v0">
<siteType>GeneratedName</siteType>
<passwordType>GeneratedName</passwordType>
<result>fejrajugo</result>
</case>
<case id="v0_type_phrase" parent="v0">
<siteType>GeneratedPhrase</siteType>
<passwordType>GeneratedPhrase</passwordType>
<result>fejr jug gabsibu bax</result>
</case>
<case id="v0_counter_ceiling" parent="v0">

View File

@ -331,20 +331,20 @@ static NSOperationQueue *_mpwQueue = nil;
- (NSString *)generateLoginForSiteNamed:(NSString *)name usingKey:(MPKey *)key {
return [self generateContentForSiteNamed:name ofType:MPSiteTypeGeneratedName withCounter:1
variant:MPSiteVariantLogin context:nil usingKey:key];
variant:MPKeyPurposeIdentification context:nil usingKey:key];
}
- (NSString *)generatePasswordForSiteNamed:(NSString *)name ofType:(MPSiteType)type withCounter:(NSUInteger)counter
usingKey:(MPKey *)key {
return [self generateContentForSiteNamed:name ofType:type withCounter:counter
variant:MPSiteVariantPassword context:nil usingKey:key];
variant:MPKeyPurposeAuthentication context:nil usingKey:key];
}
- (NSString *)generateAnswerForSiteNamed:(NSString *)name onQuestion:(NSString *)question usingKey:(MPKey *)key {
return [self generateContentForSiteNamed:name ofType:MPSiteTypeGeneratedPhrase withCounter:1
variant:MPSiteVariantAnswer context:question usingKey:key];
variant:MPKeyPurposeRecovery context:question usingKey:key];
}
- (NSString *)generateContentForSiteNamed:(NSString *)name ofType:(MPSiteType)type withCounter:(NSUInteger)counter

View File

@ -52,9 +52,9 @@ int main(int argc, char *const argv[]) {
const char *masterPassword = "banana colored duckling";
const char *siteName = "masterpasswordapp.com";
const uint32_t siteCounter = 1;
const MPSiteType siteType = MPSiteTypeDefault;
const MPSiteVariant siteVariant = MPSiteVariantPassword;
const char *siteContext = NULL;
const MPPasswordType passwordType = MPPasswordTypeDefault;
const MPKeyPurpose keyPurpose = MPKeyPurposeAuthentication;
const char *keyContext = NULL;
struct timeval startTime;
unsigned int iterations;
float percent;
@ -112,9 +112,9 @@ int main(int argc, char *const argv[]) {
ftl( "Could not allocate master key: %d\n", errno );
MPSiteKey siteKey = mpw_siteKey(
masterKey, siteName, siteCounter, siteVariant, siteContext, MPAlgorithmVersionCurrent );
masterKey, siteName, siteCounter, keyPurpose, keyContext, MPAlgorithmVersionCurrent );
free( (void *)mpw_sitePassword(
siteKey, siteType, MPAlgorithmVersionCurrent ) );
siteKey, passwordType, MPAlgorithmVersionCurrent ) );
free( (void *)masterKey );
free( (void *)siteKey );

View File

@ -16,20 +16,18 @@
#include "mpw-marshall.h"
#define MP_env_fullName "MP_FULLNAME"
#define MP_env_siteType "MP_SITETYPE"
#define MP_env_siteCounter "MP_SITECOUNTER"
#define MP_env_algorithm "MP_ALGORITHM"
static void usage() {
inf( ""
"Usage: mpw [-u name] [-t type] [-c counter] [-a algorithm] [-V variant] [-C context] [-v|-q] [-h] site\n\n" );
"Usage: mpw [-u name] [-t type] [-c counter] [-a algorithm] [-p purpose] [-C context] [-v|-q] [-h] site\n\n" );
inf( ""
" -u name Specify the full name of the user.\n"
" Defaults to %s in env or prompts.\n\n", MP_env_fullName );
inf( ""
" -t type Specify the password's template.\n"
" Defaults to %s in env or 'long' for password, 'name' for login.\n"
" Defaults to 'long' for auth, 'name' for ident and 'phrase' for recovery.\n"
" x, max, maximum | 20 characters, contains symbols.\n"
" l, long | Copy-friendly, 14 characters, contains symbols.\n"
" m, med, medium | Copy-friendly, 8 characters, contains symbols.\n"
@ -37,26 +35,25 @@ static void usage() {
" s, short | Copy-friendly, 4 characters, no symbols.\n"
" i, pin | 4 numbers.\n"
" n, name | 9 letter name.\n"
" p, phrase | 20 character sentence.\n\n", MP_env_siteType );
" p, phrase | 20 character sentence.\n\n" );
inf( ""
" -c counter The value of the counter.\n"
" Defaults to %s in env or 1.\n\n", MP_env_siteCounter );
" Defaults to 1.\n\n" );
inf( ""
" -a version The algorithm version to use.\n"
" Defaults to %s in env or %d.\n\n", MP_env_algorithm, MPAlgorithmVersionCurrent );
inf( ""
" -V variant The kind of content to generate.\n"
" -p purpose The purpose of the generated token.\n"
" Defaults to 'password'.\n"
" p, password | The password to log in with.\n"
" l, login | The username to log in as.\n"
" a, answer | The answer to a security question.\n\n" );
" a, auth | An authentication token such as a password.\n"
" i, ident | An identification token such as a username.\n"
" r, rec | A recovery token such as a security answer.\n\n" );
inf( ""
" -C context A variant-specific context.\n"
" -C context A purpose-specific context.\n"
" Defaults to empty.\n"
" -V p, password | Doesn't currently use a context.\n"
" -V l, login | Doesn't currently use a context.\n"
" -V a, answer | Empty for a universal site answer or\n"
" | the most significant word(s) of the question.\n\n" );
" -p a, auth | -\n"
" -p i, ident | -\n"
" -p r, rec | Most significant word in security question.\n\n" );
inf( ""
" -v Increase output verbosity (can be repeated).\n\n" );
inf( ""
@ -64,10 +61,8 @@ static void usage() {
inf( ""
" ENVIRONMENT\n\n"
" %-14s | The full name of the user (see -u).\n"
" %-14s | The default password template (see -t).\n"
" %-14s | The default counter value (see -c).\n"
" %-14s | The default algorithm version (see -a).\n\n",
MP_env_fullName, MP_env_siteType, MP_env_siteCounter, MP_env_algorithm );
MP_env_fullName, MP_env_algorithm );
exit( 0 );
}
@ -111,16 +106,15 @@ static char *getline_prompt(const char *prompt) {
int main(int argc, char *const argv[]) {
// Master Password defaults.
const char *fullName = NULL, *masterPassword = NULL, *siteName = NULL;
MPSiteType siteType = MPSiteTypeDefault;
MPSiteVariant siteVariant = MPSiteVariantPassword;
const char *fullName = NULL, *masterPassword = NULL, *siteName = NULL, *keyContext = NULL;
MPPasswordType passwordType = MPPasswordTypeDefault;
MPKeyPurpose keyPurpose = MPKeyPurposeAuthentication;
MPAlgorithmVersion algorithmVersion = MPAlgorithmVersionCurrent;
uint32_t siteCounter = 1;
// Read the environment.
const char *fullNameArg = getenv( MP_env_fullName ), *masterPasswordArg = NULL, *siteNameArg = NULL;
const char *siteTypeArg = getenv( MP_env_siteType ), *siteVariantArg = NULL, *siteContextArg = NULL;
const char *siteCounterArg = getenv( MP_env_siteCounter );
const char *passwordTypeArg = NULL, *keyPurposeArg = NULL, *keyContextArg = NULL, *siteCounterArg = NULL;
const char *algorithmVersionArg = getenv( MP_env_algorithm );
// Read the command-line options.
@ -134,19 +128,19 @@ int main(int argc, char *const argv[]) {
masterPasswordArg = optarg;
break;
case 't':
siteTypeArg = optarg;
passwordTypeArg = optarg;
break;
case 'c':
siteCounterArg = optarg;
break;
case 'V':
siteVariantArg = optarg;
case 'p':
keyPurposeArg = optarg;
break;
case 'a':
algorithmVersionArg = optarg;
break;
case 'C':
siteContextArg = optarg;
keyContextArg = optarg;
break;
case 'v':
++mpw_verbosity;
@ -183,9 +177,9 @@ int main(int argc, char *const argv[]) {
fullNameArg = fullNameArg && strlen( fullNameArg )? fullNameArg: NULL;
masterPasswordArg = masterPasswordArg && strlen( masterPasswordArg )? masterPasswordArg: NULL;
siteNameArg = siteNameArg && strlen( siteNameArg )? siteNameArg: NULL;
siteTypeArg = siteTypeArg && strlen( siteTypeArg )? siteTypeArg: NULL;
siteVariantArg = siteVariantArg && strlen( siteVariantArg )? siteVariantArg: NULL;
siteContextArg = siteContextArg && strlen( siteContextArg )? siteContextArg: NULL;
passwordTypeArg = passwordTypeArg && strlen( passwordTypeArg )? passwordTypeArg: NULL;
keyPurposeArg = keyPurposeArg && strlen( keyPurposeArg )? keyPurposeArg: NULL;
keyContextArg = keyContextArg && strlen( keyContextArg )? keyContextArg: NULL;
siteCounterArg = siteCounterArg && strlen( siteCounterArg )? siteCounterArg: NULL;
algorithmVersionArg = algorithmVersionArg && strlen( algorithmVersionArg )? algorithmVersionArg: NULL;
@ -239,11 +233,11 @@ int main(int argc, char *const argv[]) {
fullName = strdup( user->name );
masterPassword = strdup( user->masterPassword );
algorithmVersion = user->algorithm;
siteType = user->defaultType;
passwordType = user->defaultType;
for (size_t s = 0; s < user->sites_count; ++s) {
MPMarshalledSite site = user->sites[s];
if (strcmp( siteName, site.name ) == 0) {
siteType = site.type;
passwordType = site.type;
siteCounter = site.counter;
algorithmVersion = site.algorithm;
break;
@ -285,14 +279,16 @@ int main(int argc, char *const argv[]) {
ftl( "Invalid site counter: %s\n", siteCounterArg );
siteCounter = (uint32_t)siteCounterInt;
}
if (siteVariantArg)
siteVariant = mpw_variantWithName( siteVariantArg );
if (siteVariant == MPSiteVariantLogin)
siteType = MPSiteTypeGeneratedName;
if (siteVariant == MPSiteVariantAnswer)
siteType = MPSiteTypeGeneratedPhrase;
if (siteTypeArg)
siteType = mpw_typeWithName( siteTypeArg );
if (keyPurposeArg)
keyPurpose = mpw_purposeWithName( keyPurposeArg );
if (keyPurpose == MPKeyPurposeIdentification)
passwordType = MPPasswordTypeGeneratedName;
if (keyPurpose == MPKeyPurposeRecovery)
passwordType = MPPasswordTypeGeneratedPhrase;
if (passwordTypeArg)
passwordType = mpw_typeWithName( passwordTypeArg );
if (keyContextArg)
keyContext = strdup( keyContextArg );
// Summarize operation.
const char *identicon = mpw_identicon( fullName, masterPassword );
@ -303,7 +299,7 @@ int main(int argc, char *const argv[]) {
trc( "masterPassword : %s\n", masterPassword );
dbg( "identicon : %s\n", identicon );
dbg( "siteName : %s\n", siteName );
dbg( "siteType : %u\n", siteType );
dbg( "passwordType : %u\n", passwordType );
dbg( "algorithmVersion : %u\n", algorithmVersion );
dbg( "siteCounter : %u\n", siteCounter );
dbg( "-----------------\n\n" );
@ -318,11 +314,12 @@ int main(int argc, char *const argv[]) {
if (!masterKey)
ftl( "Couldn't derive master key." );
MPSiteKey siteKey = mpw_siteKey( masterKey, siteName, siteCounter, siteVariant, siteContextArg, algorithmVersion );
const char *sitePassword = mpw_sitePassword(siteKey, siteType, algorithmVersion );
MPSiteKey siteKey = mpw_siteKey( masterKey, siteName, siteCounter, keyPurpose, keyContext, algorithmVersion );
const char *sitePassword = mpw_sitePassword(siteKey, passwordType, algorithmVersion );
mpw_free( masterKey, MPMasterKeySize );
mpw_free( siteKey, MPSiteKeySize );
mpw_free_string( siteName );
mpw_free_string( keyContext );
if (!sitePassword)
ftl( "Couldn't derive site password." );

View File

@ -1,5 +1,3 @@
#define _GNU_SOURCE
#include <stdio.h>
#include <stdlib.h>
@ -30,13 +28,13 @@ int main(int argc, char *const argv[]) {
xmlChar *keyID = mpw_xmlTestCaseString( testCase, "keyID" );
xmlChar *siteName = mpw_xmlTestCaseString( testCase, "siteName" );
uint32_t siteCounter = mpw_xmlTestCaseInteger( testCase, "siteCounter" );
xmlChar *siteTypeString = mpw_xmlTestCaseString( testCase, "siteType" );
xmlChar *siteVariantString = mpw_xmlTestCaseString( testCase, "siteVariant" );
xmlChar *siteContext = mpw_xmlTestCaseString( testCase, "siteContext" );
xmlChar *passwordTypeString = mpw_xmlTestCaseString( testCase, "passwordType" );
xmlChar *keyPurposeString = mpw_xmlTestCaseString( testCase, "keyPurpose" );
xmlChar *keyContext = mpw_xmlTestCaseString( testCase, "keyContext" );
xmlChar *result = mpw_xmlTestCaseString( testCase, "result" );
MPSiteType siteType = mpw_typeWithName( (char *)siteTypeString );
MPSiteVariant siteVariant = mpw_variantWithName( (char *)siteVariantString );
MPPasswordType siteType = mpw_typeWithName( (char *)passwordTypeString );
MPKeyPurpose siteVariant = mpw_purposeWithName( (char *)keyPurposeString );
// Run the test case.
fprintf( stdout, "test case %s... ", id );
@ -53,7 +51,7 @@ int main(int argc, char *const argv[]) {
// 2. calculate the site password.
MPSiteKey siteKey = mpw_siteKey(
masterKey, (char *)siteName, siteCounter, siteVariant, (char *)siteContext, algorithm );
masterKey, (char *)siteName, siteCounter, siteVariant, (char *)keyContext, algorithm );
const char *sitePassword = mpw_sitePassword(
siteKey, siteType, algorithm );
mpw_free( masterKey, MPMasterKeySize );
@ -77,9 +75,9 @@ int main(int argc, char *const argv[]) {
xmlFree( masterPassword );
xmlFree( keyID );
xmlFree( siteName );
xmlFree( siteTypeString );
xmlFree( siteVariantString );
xmlFree( siteContext );
xmlFree( passwordTypeString );
xmlFree( keyPurposeString );
xmlFree( keyContext );
xmlFree( result );
}