Rename identifiers to align better with their meaning (siteVariant -> keyPurpose, siteContext -> keyContext, siteType -> passwordType).
This commit is contained in:
parent
3c5cb1673a
commit
9d5105a9e5
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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) {
|
||||
|
@ -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(
|
||||
|
@ -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 "";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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.
|
||||
|
@ -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)
|
||||
|
@ -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#&@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#&@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#&@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">
|
||||
|
@ -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
|
||||
|
@ -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 );
|
||||
|
||||
|
@ -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." );
|
||||
|
||||
|
@ -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 );
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user