From 9d5105a9e5bfefaeadfe8792159c154f4fdb4b6f Mon Sep 17 00:00:00 2001 From: Maarten Billemont Date: Tue, 1 Aug 2017 13:45:54 -0400 Subject: [PATCH] Rename identifiers to align better with their meaning (siteVariant -> keyPurpose, siteContext -> keyContext, siteType -> passwordType). --- core/c/mpw-algorithm.c | 20 ++-- core/c/mpw-algorithm.h | 4 +- core/c/mpw-algorithm_v0.c | 63 +++++----- core/c/mpw-algorithm_v1.c | 61 +++++----- core/c/mpw-algorithm_v2.c | 61 +++++----- core/c/mpw-algorithm_v3.c | 63 +++++----- core/c/mpw-marshall.c | 26 ++-- core/c/mpw-marshall.h | 6 +- core/c/mpw-types.c | 113 ++++++++---------- core/c/mpw-types.h | 64 +++++----- core/c/mpw-util.c | 1 + .../tests/src/main/resources/mpw_tests.xml | 100 ++++++++-------- platform-darwin/Source/MPAlgorithmV0.m | 6 +- platform-independent/cli-c/cli/mpw-bench.c | 10 +- platform-independent/cli-c/cli/mpw-cli.c | 83 +++++++------ platform-independent/cli-c/cli/mpw-tests.c | 20 ++-- 16 files changed, 351 insertions(+), 350 deletions(-) diff --git a/core/c/mpw-algorithm.c b/core/c/mpw-algorithm.c index 9d428058..678eba57 100644 --- a/core/c/mpw-algorithm.c +++ b/core/c/mpw-algorithm.c @@ -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; diff --git a/core/c/mpw-algorithm.h b/core/c/mpw-algorithm.h index 59bc7b4e..4695ac58 100644 --- a/core/c/mpw-algorithm.h +++ b/core/c/mpw-algorithm.h @@ -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 diff --git a/core/c/mpw-algorithm_v0.c b/core/c/mpw-algorithm_v0.c index de5684d4..e29a4167 100644 --- a/core/c/mpw-algorithm_v0.c +++ b/core/c/mpw-algorithm_v0.c @@ -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? "": 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? "": 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; diff --git a/core/c/mpw-algorithm_v1.c b/core/c/mpw-algorithm_v1.c index 6b987daa..b3aff97c 100644 --- a/core/c/mpw-algorithm_v1.c +++ b/core/c/mpw-algorithm_v1.c @@ -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? "": 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? "": 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; diff --git a/core/c/mpw-algorithm_v2.c b/core/c/mpw-algorithm_v2.c index e59b3773..23c24a63 100644 --- a/core/c/mpw-algorithm_v2.c +++ b/core/c/mpw-algorithm_v2.c @@ -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? "": 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? "": 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; diff --git a/core/c/mpw-algorithm_v3.c b/core/c/mpw-algorithm_v3.c index 5fe54e18..4a38c861 100644 --- a/core/c/mpw-algorithm_v3.c +++ b/core/c/mpw-algorithm_v3.c @@ -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? "": 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? "": 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; diff --git a/core/c/mpw-marshall.c b/core/c/mpw-marshall.c index 65380b12..acc12b0f 100644 --- a/core/c/mpw-marshall.c +++ b/core/c/mpw-marshall.c @@ -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) { diff --git a/core/c/mpw-marshall.h b/core/c/mpw-marshall.h index 5af21b0f..f487f72c 100644 --- a/core/c/mpw-marshall.h +++ b/core/c/mpw-marshall.h @@ -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( diff --git a/core/c/mpw-types.c b/core/c/mpw-types.c index c66e8840..379333d0 100644 --- a/core/c/mpw-types.c +++ b/core/c/mpw-types.c @@ -29,54 +29,53 @@ #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; size_t stdTypeNameSize = strlen( typeName ); - if (strstr(typeName, "Generated" ) == typeName) + if (strstr( typeName, "Generated" ) == typeName) stdTypeNameSize -= (stdTypeNameOffset = strlen( "Generated" )); char stdTypeName[stdTypeNameSize + 1]; for (size_t c = 0; c < stdTypeNameSize; ++c) 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 ""; } } } diff --git a/core/c/mpw-types.h b/core/c/mpw-types.h index 9d557fe2..d1e49588 100644 --- a/core/c/mpw-types.h +++ b/core/c/mpw-types.h @@ -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. diff --git a/core/c/mpw-util.c b/core/c/mpw-util.c index 465755be..4236b0e9 100644 --- a/core/c/mpw-util.c +++ b/core/c/mpw-util.c @@ -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) diff --git a/core/java/tests/src/main/resources/mpw_tests.xml b/core/java/tests/src/main/resources/mpw_tests.xml index 34bb460e..ed83d1d6 100644 --- a/core/java/tests/src/main/resources/mpw_tests.xml +++ b/core/java/tests/src/main/resources/mpw_tests.xml @@ -7,8 +7,8 @@ 98EEF4D1DF46D849574A82A03C3177056B15DFFCA29BB3899DE4628453675302 masterpasswordapp.com 1 - GeneratedLong - Password + GeneratedLong + Password @@ -32,45 +32,45 @@ LiheCuwhSerz6) - Login - GeneratedName + Login + GeneratedName wohzaqage - Answer - GeneratedPhrase + Answer + GeneratedPhrase xin diyjiqoja hubu - question + question xogx tem cegyiva jab - GeneratedMaximum + GeneratedMaximum W6@692^B1#&@gVdSdLZ@ - GeneratedMedium + GeneratedMedium Jej2$Quv - GeneratedBasic + GeneratedBasic WAo2xIg6 - GeneratedShort + GeneratedShort Jej2 - GeneratedPIN + GeneratedPIN 7662 - GeneratedName + GeneratedName jejraquvo - GeneratedPhrase + GeneratedPhrase jejr quv cabsibu tam @@ -98,45 +98,45 @@ LiheCuwhSerz6) - Login - GeneratedName + Login + GeneratedName wohzaqage - Answer - GeneratedPhrase + Answer + GeneratedPhrase xin diyjiqoja hubu - question + question xogx tem cegyiva jab - GeneratedMaximum + GeneratedMaximum W6@692^B1#&@gVdSdLZ@ - GeneratedMedium + GeneratedMedium Jej2$Quv - GeneratedBasic + GeneratedBasic WAo2xIg6 - GeneratedShort + GeneratedShort Jej2 - GeneratedPIN + GeneratedPIN 7662 - GeneratedName + GeneratedName jejraquvo - GeneratedPhrase + GeneratedPhrase jejr quv cabsibu tam @@ -164,45 +164,45 @@ WawiYarp2@Kodh - Login - GeneratedName + Login + GeneratedName wohzaqage - Answer - GeneratedPhrase + Answer + GeneratedPhrase xin diyjiqoja hubu - question + question xogx tem cegyiva jab - GeneratedMaximum + GeneratedMaximum W6@692^B1#&@gVdSdLZ@ - GeneratedMedium + GeneratedMedium Jej2$Quv - GeneratedBasic + GeneratedBasic WAo2xIg6 - GeneratedShort + GeneratedShort Jej2 - GeneratedPIN + GeneratedPIN 7662 - GeneratedName + GeneratedName jejraquvo - GeneratedPhrase + GeneratedPhrase jejr quv cabsibu tam @@ -230,45 +230,45 @@ HahiVana2@Nole - Login - GeneratedName + Login + GeneratedName lozwajave - Answer - GeneratedPhrase + Answer + GeneratedPhrase miy lirfijoja dubu - question + question movm bex gevrica jaf - GeneratedMaximum + GeneratedMaximum w1!3bA3icmRAc)SS@lwl - GeneratedMedium + GeneratedMedium Fej7]Jug - GeneratedBasic + GeneratedBasic wvH7irC1 - GeneratedShort + GeneratedShort Fej7 - GeneratedPIN + GeneratedPIN 2117 - GeneratedName + GeneratedName fejrajugo - GeneratedPhrase + GeneratedPhrase fejr jug gabsibu bax diff --git a/platform-darwin/Source/MPAlgorithmV0.m b/platform-darwin/Source/MPAlgorithmV0.m index f5c065d5..fda2c012 100644 --- a/platform-darwin/Source/MPAlgorithmV0.m +++ b/platform-darwin/Source/MPAlgorithmV0.m @@ -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 diff --git a/platform-independent/cli-c/cli/mpw-bench.c b/platform-independent/cli-c/cli/mpw-bench.c index ed0eb4a7..0f6e8857 100644 --- a/platform-independent/cli-c/cli/mpw-bench.c +++ b/platform-independent/cli-c/cli/mpw-bench.c @@ -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 ); diff --git a/platform-independent/cli-c/cli/mpw-cli.c b/platform-independent/cli-c/cli/mpw-cli.c index c06adaf8..7a83058e 100644 --- a/platform-independent/cli-c/cli/mpw-cli.c +++ b/platform-independent/cli-c/cli/mpw-cli.c @@ -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." ); diff --git a/platform-independent/cli-c/cli/mpw-tests.c b/platform-independent/cli-c/cli/mpw-tests.c index dbf9315e..e8178220 100644 --- a/platform-independent/cli-c/cli/mpw-tests.c +++ b/platform-independent/cli-c/cli/mpw-tests.c @@ -1,5 +1,3 @@ -#define _GNU_SOURCE - #include #include @@ -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 ); }