diff --git a/core/c/mpw-algorithm.c b/core/c/mpw-algorithm.c index 0833ebac..63b925cf 100644 --- a/core/c/mpw-algorithm.c +++ b/core/c/mpw-algorithm.c @@ -72,69 +72,98 @@ MPSiteKey mpw_siteKey( } } -const char *mpw_sitePassword( - MPSiteKey siteKey, const MPPasswordType passwordType, const MPAlgorithmVersion algorithmVersion) { +const char *mpw_siteResult( + MPMasterKey masterKey, const char *siteName, const MPCounterValue siteCounter, + const MPKeyPurpose keyPurpose, const char *keyContext, + const MPResultType resultType, const char *resultParam, + const MPAlgorithmVersion algorithmVersion) { - trc( "-- mpw_sitePassword (algorithm: %u)\n", algorithmVersion ); - trc( "passwordType: %d (%s)\n", passwordType, mpw_nameForType( passwordType ) ); + MPSiteKey siteKey = mpw_siteKey_v0( masterKey, siteName, siteCounter, keyPurpose, keyContext ); if (!siteKey) return NULL; - switch (algorithmVersion) { - case MPAlgorithmVersion0: - return mpw_sitePassword_v0( siteKey, passwordType ); - case MPAlgorithmVersion1: - return mpw_sitePassword_v1( siteKey, passwordType ); - case MPAlgorithmVersion2: - return mpw_sitePassword_v2( siteKey, passwordType ); - case MPAlgorithmVersion3: - return mpw_sitePassword_v3( siteKey, passwordType ); - default: - err( "Unsupported version: %d\n", algorithmVersion ); - return NULL; + trc( "-- mpw_siteResult (algorithm: %u)\n", algorithmVersion ); + trc( "resultType: %d (%s)\n", resultType, mpw_nameForType( resultType ) ); + trc( "resultParam: %s\n", resultParam ); + + char *sitePassword = NULL; + if (resultType & MPResultTypeClassTemplate) { + switch (algorithmVersion) { + case MPAlgorithmVersion0: + return mpw_sitePasswordFromTemplate_v0( masterKey, siteKey, resultType, resultParam ); + case MPAlgorithmVersion1: + return mpw_sitePasswordFromTemplate_v1( masterKey, siteKey, resultType, resultParam ); + case MPAlgorithmVersion2: + return mpw_sitePasswordFromTemplate_v2( masterKey, siteKey, resultType, resultParam ); + case MPAlgorithmVersion3: + return mpw_sitePasswordFromTemplate_v3( masterKey, siteKey, resultType, resultParam ); + default: + err( "Unsupported version: %d\n", algorithmVersion ); + return NULL; + } } + else if (resultType & MPResultTypeClassState) { + switch (algorithmVersion) { + case MPAlgorithmVersion0: + return mpw_sitePasswordFromCrypt_v0( masterKey, siteKey, resultType, resultParam ); + case MPAlgorithmVersion1: + return mpw_sitePasswordFromCrypt_v1( masterKey, siteKey, resultType, resultParam ); + case MPAlgorithmVersion2: + return mpw_sitePasswordFromCrypt_v2( masterKey, siteKey, resultType, resultParam ); + case MPAlgorithmVersion3: + return mpw_sitePasswordFromCrypt_v3( masterKey, siteKey, resultType, resultParam ); + default: + err( "Unsupported version: %d\n", algorithmVersion ); + return NULL; + } + } + else if (resultType & MPResultTypeClassDerive) { + switch (algorithmVersion) { + case MPAlgorithmVersion0: + return mpw_sitePasswordFromDerive_v0( masterKey, siteKey, resultType, resultParam ); + case MPAlgorithmVersion1: + return mpw_sitePasswordFromDerive_v1( masterKey, siteKey, resultType, resultParam ); + case MPAlgorithmVersion2: + return mpw_sitePasswordFromDerive_v2( masterKey, siteKey, resultType, resultParam ); + case MPAlgorithmVersion3: + return mpw_sitePasswordFromDerive_v3( masterKey, siteKey, resultType, resultParam ); + default: + err( "Unsupported version: %d\n", algorithmVersion ); + return NULL; + } + } + else { + err( "Unsupported password type: %d\n", resultType ); + } + + return sitePassword; } -const char *mpw_encrypt( - MPMasterKey masterKey, const char *plainText, const MPAlgorithmVersion algorithmVersion) { +const char *mpw_siteState( + MPMasterKey masterKey, const char *siteName, const MPCounterValue siteCounter, + const MPKeyPurpose keyPurpose, const char *keyContext, + const MPResultType resultType, const char *state, + const MPAlgorithmVersion algorithmVersion) { - trc( "-- mpw_encrypt (algorithm: %u)\n", algorithmVersion ); - trc( "plainText: %s = %s\n", plainText, mpw_hex( plainText, sizeof( plainText ) ) ); - if (!masterKey || !plainText) + MPSiteKey siteKey = mpw_siteKey_v0( masterKey, siteName, siteCounter, keyPurpose, keyContext ); + if (!siteKey) + return NULL; + + trc( "-- mpw_siteState (algorithm: %u)\n", algorithmVersion ); + trc( "resultType: %d (%s)\n", resultType, mpw_nameForType( resultType ) ); + trc( "state: %s\n", state ); + if (!masterKey || !state) return NULL; switch (algorithmVersion) { case MPAlgorithmVersion0: - return mpw_encrypt_v0( masterKey, plainText ); + return mpw_siteState_v0( masterKey, siteKey, resultType, state ); case MPAlgorithmVersion1: - return mpw_encrypt_v1( masterKey, plainText ); + return mpw_siteState_v1( masterKey, siteKey, resultType, state ); case MPAlgorithmVersion2: - return mpw_encrypt_v2( masterKey, plainText ); + return mpw_siteState_v2( masterKey, siteKey, resultType, state ); case MPAlgorithmVersion3: - return mpw_encrypt_v3( masterKey, plainText ); - default: - err( "Unsupported version: %d\n", algorithmVersion ); - return NULL; - } -} - -const char *mpw_decrypt( - MPMasterKey masterKey, const char *cipherText, const MPAlgorithmVersion algorithmVersion) { - - trc( "-- mpw_decrypt (algorithm: %u)\n", algorithmVersion ); - trc( "cipherText: %s = %s\n", cipherText, mpw_hex( cipherText, sizeof( cipherText ) ) ); - if (!masterKey || !cipherText) - return NULL; - - switch (algorithmVersion) { - case MPAlgorithmVersion0: - return mpw_decrypt_v0( masterKey, cipherText ); - case MPAlgorithmVersion1: - return mpw_decrypt_v1( masterKey, cipherText ); - case MPAlgorithmVersion2: - return mpw_decrypt_v2( masterKey, cipherText ); - case MPAlgorithmVersion3: - return mpw_decrypt_v3( masterKey, cipherText ); + return mpw_siteState_v3( masterKey, siteKey, resultType, state ); default: err( "Unsupported version: %d\n", algorithmVersion ); return NULL; diff --git a/core/c/mpw-algorithm.h b/core/c/mpw-algorithm.h index d661077d..59ecd48e 100644 --- a/core/c/mpw-algorithm.h +++ b/core/c/mpw-algorithm.h @@ -50,17 +50,18 @@ MPSiteKey mpw_siteKey( /** 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 MPPasswordType passwordType, const MPAlgorithmVersion algorithmVersion); +const char *mpw_siteResult( + MPMasterKey masterKey, const char *siteName, const MPCounterValue siteCounter, + const MPKeyPurpose keyPurpose, const char *keyContext, + const MPResultType resultType, const char *resultParam, + const MPAlgorithmVersion algorithmVersion); /** Perform symmetric encryption on a secret token's plainText. * @return The newly allocated cipherText of the secret token encrypted by the masterKey. */ -const char *mpw_encrypt( - MPMasterKey masterKey, const char *plainText, const MPAlgorithmVersion algorithmVersion); - -/** Perform symmetric decryption on a secret token's cipherText. - * @return The newly allocated plainText of the secret token decrypted by the masterKey. */ -const char *mpw_decrypt( - MPMasterKey masterKey, const char *cipherText, const MPAlgorithmVersion algorithmVersion); +const char *mpw_siteState( + MPMasterKey masterKey, const char *siteName, const MPCounterValue siteCounter, + const MPKeyPurpose keyPurpose, const char *keyContext, + const MPResultType resultType, const char *state, + const MPAlgorithmVersion algorithmVersion); #endif // _MPW_ALGORITHM_H diff --git a/core/c/mpw-algorithm_v0.c b/core/c/mpw-algorithm_v0.c index d40f59b1..69d7c22c 100644 --- a/core/c/mpw-algorithm_v0.c +++ b/core/c/mpw-algorithm_v0.c @@ -29,7 +29,7 @@ #define MP_p 2U // Algorithm version helpers. -static const char *mpw_templateForType_v0(MPPasswordType type, uint16_t seedByte) { +static const char *mpw_templateForType_v0(MPResultType type, uint16_t seedByte) { size_t count = 0; const char **templates = mpw_templatesForType( type, &count ); @@ -70,7 +70,7 @@ static MPMasterKey mpw_masterKey_v0( // Calculate the master key. trc( "masterKey: scrypt( masterPassword, masterKeySalt, N=%lu, r=%u, p=%u )\n", MP_N, MP_r, MP_p ); - MPMasterKey masterKey = mpw_scrypt( MPMasterKeySize, masterPassword, masterKeySalt, masterKeySaltSize, MP_N, MP_r, MP_p ); + MPMasterKey masterKey = mpw_kdf_scrypt( MPMasterKeySize, masterPassword, masterKeySalt, masterKeySaltSize, MP_N, MP_r, MP_p ); mpw_free( masterKeySalt, masterKeySaltSize ); if (!masterKey) { err( "Could not allocate master key: %s\n", strerror( errno ) ); @@ -113,10 +113,10 @@ static MPSiteKey mpw_siteKey_v0( trc( "siteKey: hmac-sha256( masterKey.id=%s, siteSalt )\n", mpw_id_buf( masterKey, MPMasterKeySize ) ); - MPSiteKey siteKey = mpw_hmac_sha256( masterKey, MPMasterKeySize, siteSalt, siteSaltSize ); + MPSiteKey siteKey = mpw_hash_hmac_sha256( masterKey, MPMasterKeySize, siteSalt, siteSaltSize ); mpw_free( siteSalt, siteSaltSize ); if (!siteKey) { - err( "Could not allocate site key: %s\n", strerror( errno ) ); + err( "Could not derive site key: %s\n", strerror( errno ) ); return NULL; } trc( " => siteKey.id: %s\n", mpw_id_buf( siteKey, MPSiteKeySize ) ); @@ -124,12 +124,12 @@ static MPSiteKey mpw_siteKey_v0( return siteKey; } -static const char *mpw_sitePassword_v0( - MPSiteKey siteKey, const MPPasswordType passwordType) { +static const char *mpw_sitePasswordFromTemplate_v0( + MPMasterKey masterKey, MPSiteKey siteKey, const MPResultType resultType, const char *resultParam) { // Determine the template. const char *_siteKey = (const char *)siteKey; - const char *template = mpw_templateForType_v0( passwordType, htons( _siteKey[0] ) ); + const char *template = mpw_templateForType_v0( resultType, htons( _siteKey[0] ) ); trc( "template: %u => %s\n", htons( _siteKey[0] ), template ); if (!template) return NULL; @@ -139,7 +139,7 @@ static const char *mpw_sitePassword_v0( } // Encode the password from the seed using the template. - char *const sitePassword = calloc( strlen( template ) + 1, sizeof( char ) ); + char *sitePassword = calloc( strlen( template ) + 1, sizeof( char ) ); for (size_t c = 0; c < strlen( template ); ++c) { sitePassword[c] = mpw_characterFromClass_v0( template[c], htons( _siteKey[c + 1] ) ); trc( " - class: %c, index: %5u (0x%02hX) => character: %c\n", @@ -150,8 +150,80 @@ static const char *mpw_sitePassword_v0( return sitePassword; } -const char *mpw_encrypt_v0( - MPMasterKey masterKey, const char *plainText) { +static const char *mpw_sitePasswordFromCrypt_v0( + MPMasterKey masterKey, MPSiteKey siteKey, const MPResultType resultType, const char *cipherText) { + + if (!cipherText) { + err( "Missing encrypted state.\n" ); + return NULL; + } + + // Base64-decode + uint8_t *cipherBuf = calloc( 1, mpw_base64_decode_max( cipherText ) ); + size_t bufSize = (size_t)mpw_base64_decode( cipherBuf, cipherText ); + if ((int)bufSize < 0) { + err( "Base64 decoding error." ); + mpw_free( cipherBuf, mpw_base64_decode_max( cipherText ) ); + return NULL; + } + trc( "b64 decoded: %zu bytes = %s\n", bufSize, mpw_hex( cipherBuf, bufSize ) ); + + // Decrypt + const uint8_t *plainBytes = mpw_aes_decrypt( masterKey, MPMasterKeySize, cipherBuf, bufSize ); + const char *plainText = strndup( (char *)plainBytes, bufSize ); + mpw_free( plainBytes, bufSize ); + if (!plainText) + err( "AES decryption error: %s\n", strerror( errno ) ); + trc( "decrypted -> plainText: %s = %s\n", plainText, mpw_hex( plainText, sizeof( plainText ) ) ); + mpw_free( cipherBuf, bufSize ); + + return plainText; +} + +static const char *mpw_sitePasswordFromDerive_v0( + MPMasterKey masterKey, MPSiteKey siteKey, const MPResultType resultType, const char *resultParam) { + + switch (resultType) { + case MPResultTypeDeriveKey: { + if (!resultParam) { + err( "Missing key size parameter.\n" ); + return NULL; + } + int resultParamInt = atoi( resultParam ); + if (resultParamInt <= 0 || resultParamInt > UINT16_MAX || resultParamInt % 8 != 0) { + err( "Parameter is not a valid key size: %s\n", resultParam ); + return NULL; + } + uint16_t keySize = (uint16_t)(resultParamInt / 8); + trc( "keySize: %u\n", keySize ); + + // Derive key + const uint8_t *resultKey = mpw_kdf_blake2b( keySize, siteKey, MPSiteKeySize, NULL, 0, 0, NULL ); + if (!resultKey) { + err( "Could not derive result key: %s\n", strerror( errno ) ); + return NULL; + } + + // Base64-encode + size_t b64Max = mpw_base64_encode_max( keySize ); + char *sitePassword = calloc( 1, b64Max + 1 ); + if (mpw_base64_encode( sitePassword, resultKey, keySize ) < 0) { + err( "Base64 encoding error." ); + mpw_free_string( sitePassword ); + sitePassword = NULL; + } + trc( "b64 encoded -> key.id: %s\n", mpw_id_buf( sitePassword, strlen( sitePassword ) ) ); + + return sitePassword; + } + default: + err( "Unsupported derived password type: %d\n", resultType ); + return NULL; + } +} + +static const char *mpw_siteState_v0( + MPMasterKey masterKey, MPSiteKey siteKey, const MPResultType resultType, const char *plainText) { // Encrypt size_t bufSize = strlen( plainText ); @@ -175,28 +247,3 @@ const char *mpw_encrypt_v0( return cipherText; } - -const char *mpw_decrypt_v0( - MPMasterKey masterKey, const char *cipherText) { - - // Base64-decode - uint8_t *cipherBuf = calloc( 1, mpw_base64_decode_max( cipherText ) ); - size_t bufSize = (size_t)mpw_base64_decode( cipherBuf, cipherText ); - if ((int)bufSize < 0) { - err( "Base64 decoding error." ); - mpw_free( cipherBuf, mpw_base64_decode_max( cipherText ) ); - return NULL; - } - trc( "b64 decoded: %zu bytes = %s\n", bufSize, mpw_hex( cipherBuf, bufSize ) ); - - // Decrypt - const uint8_t *plainBytes = mpw_aes_decrypt( masterKey, MPMasterKeySize, cipherBuf, bufSize ); - const char *plainText = strndup( (char *)plainBytes, bufSize ); - mpw_free( plainBytes, bufSize ); - if (!plainText) - err( "AES decryption error: %s\n", strerror( errno ) ); - trc( "decrypted -> plainText: %s = %s\n", plainText, mpw_hex( plainText, sizeof( plainText ) ) ); - mpw_free( cipherBuf, bufSize ); - - return plainText; -} diff --git a/core/c/mpw-algorithm_v1.c b/core/c/mpw-algorithm_v1.c index b6129e13..954ccdc1 100644 --- a/core/c/mpw-algorithm_v1.c +++ b/core/c/mpw-algorithm_v1.c @@ -33,10 +33,12 @@ MPMasterKey mpw_masterKey_v0( MPSiteKey mpw_siteKey_v0( MPMasterKey masterKey, const char *siteName, const MPCounterValue siteCounter, const MPKeyPurpose keyPurpose, const char *keyContext); -const char *mpw_encrypt_v0( - MPMasterKey masterKey, const char *plainText); -const char *mpw_decrypt_v0( - MPMasterKey masterKey, const char *cipherText); +const char *mpw_sitePasswordFromCrypt_v0( + MPMasterKey masterKey, MPSiteKey siteKey, const MPResultType resultType, const char *cipherText); +const char *mpw_sitePasswordFromDerive_v0( + MPMasterKey masterKey, MPSiteKey siteKey, const MPResultType resultType, const char *resultParam); +const char *mpw_siteState_v0( + MPMasterKey masterKey, MPSiteKey siteKey, const MPResultType resultType, const char *state); // Algorithm version overrides. static MPMasterKey mpw_masterKey_v1( @@ -52,11 +54,11 @@ static MPSiteKey mpw_siteKey_v1( return mpw_siteKey_v0( masterKey, siteName, siteCounter, keyPurpose, keyContext ); } -static const char *mpw_sitePassword_v1( - MPSiteKey siteKey, const MPPasswordType passwordType) { +static const char *mpw_sitePasswordFromTemplate_v1( + MPMasterKey masterKey, MPSiteKey siteKey, const MPResultType resultType, const char *resultParam) { // Determine the template. - const char *template = mpw_templateForType( passwordType, siteKey[0] ); + const char *template = mpw_templateForType( resultType, siteKey[0] ); trc( "template: %u => %s\n", siteKey[0], template ); if (!template) return NULL; @@ -77,14 +79,20 @@ static const char *mpw_sitePassword_v1( return sitePassword; } -static const char *mpw_encrypt_v1( - MPMasterKey masterKey, const char *plainText) { +static const char *mpw_sitePasswordFromCrypt_v1( + MPMasterKey masterKey, MPSiteKey siteKey, const MPResultType resultType, const char *cipherText) { - return mpw_encrypt_v0( masterKey, plainText ); + return mpw_sitePasswordFromCrypt_v0( masterKey, siteKey, resultType, cipherText ); } -static const char *mpw_decrypt_v1( - MPMasterKey masterKey, const char *cipherText) { +static const char *mpw_sitePasswordFromDerive_v1( + MPMasterKey masterKey, MPSiteKey siteKey, const MPResultType resultType, const char *resultParam) { - return mpw_decrypt_v0( masterKey, cipherText ); + return mpw_sitePasswordFromDerive_v0( masterKey, siteKey, resultType, resultParam ); +} + +static const char *mpw_siteState_v1( + MPMasterKey masterKey, MPSiteKey siteKey, const MPResultType resultType, const char *state) { + + return mpw_siteState_v0( masterKey, siteKey, resultType, state ); } diff --git a/core/c/mpw-algorithm_v2.c b/core/c/mpw-algorithm_v2.c index 5b81dd50..574541cc 100644 --- a/core/c/mpw-algorithm_v2.c +++ b/core/c/mpw-algorithm_v2.c @@ -30,12 +30,14 @@ // Inherited functions. MPMasterKey mpw_masterKey_v1( const char *fullName, const char *masterPassword); -const char *mpw_sitePassword_v1( - MPSiteKey siteKey, const MPPasswordType passwordType); -const char *mpw_encrypt_v1( - MPMasterKey masterKey, const char *plainText); -const char *mpw_decrypt_v1( - MPMasterKey masterKey, const char *cipherText); +const char *mpw_sitePasswordFromTemplate_v1( + MPMasterKey masterKey, MPSiteKey siteKey, const MPResultType resultType, const char *resultParam); +const char *mpw_sitePasswordFromCrypt_v1( + MPMasterKey masterKey, MPSiteKey siteKey, const MPResultType resultType, const char *cipherText); +const char *mpw_sitePasswordFromDerive_v1( + MPMasterKey masterKey, MPSiteKey siteKey, const MPResultType resultType, const char *resultParam); +const char *mpw_siteState_v1( + MPMasterKey masterKey, MPSiteKey siteKey, const MPResultType resultType, const char *state); // Algorithm version overrides. static MPMasterKey mpw_masterKey_v2( @@ -76,7 +78,7 @@ static MPSiteKey mpw_siteKey_v2( trc( "siteKey: hmac-sha256( masterKey.id=%s, siteSalt )\n", mpw_id_buf( masterKey, MPMasterKeySize ) ); - MPSiteKey siteKey = mpw_hmac_sha256( masterKey, MPMasterKeySize, siteSalt, siteSaltSize ); + MPSiteKey siteKey = mpw_hash_hmac_sha256( masterKey, MPMasterKeySize, siteSalt, siteSaltSize ); mpw_free( siteSalt, siteSaltSize ); if (!siteKey) { err( "Could not allocate site key: %s\n", strerror( errno ) ); @@ -87,20 +89,26 @@ static MPSiteKey mpw_siteKey_v2( return siteKey; } -static const char *mpw_sitePassword_v2( - MPSiteKey siteKey, const MPPasswordType passwordType) { +static const char *mpw_sitePasswordFromTemplate_v2( + MPMasterKey masterKey, MPSiteKey siteKey, const MPResultType resultType, const char *resultParam) { - return mpw_sitePassword_v1( siteKey, passwordType ); + return mpw_sitePasswordFromTemplate_v1( masterKey, siteKey, resultType, resultParam ); } -static const char *mpw_encrypt_v2( - MPMasterKey masterKey, const char *plainText) { +static const char *mpw_sitePasswordFromCrypt_v2( + MPMasterKey masterKey, MPSiteKey siteKey, const MPResultType resultType, const char *cipherText) { - return mpw_encrypt_v1( masterKey, plainText ); + return mpw_sitePasswordFromCrypt_v1( masterKey, siteKey, resultType, cipherText ); } -static const char *mpw_decrypt_v2( - MPMasterKey masterKey, const char *cipherText) { +static const char *mpw_sitePasswordFromDerive_v2( + MPMasterKey masterKey, MPSiteKey siteKey, const MPResultType resultType, const char *resultParam) { - return mpw_decrypt_v1( masterKey, cipherText ); + return mpw_sitePasswordFromDerive_v1( masterKey, siteKey, resultType, resultParam ); +} + +static const char *mpw_siteState_v2( + MPMasterKey masterKey, MPSiteKey siteKey, const MPResultType resultType, const char *state) { + + return mpw_siteState_v1( masterKey, siteKey, resultType, state ); } diff --git a/core/c/mpw-algorithm_v3.c b/core/c/mpw-algorithm_v3.c index 300c2031..a033fa3d 100644 --- a/core/c/mpw-algorithm_v3.c +++ b/core/c/mpw-algorithm_v3.c @@ -31,12 +31,14 @@ MPSiteKey mpw_siteKey_v2( MPMasterKey masterKey, const char *siteName, const MPCounterValue siteCounter, const MPKeyPurpose keyPurpose, const char *keyContext); -const char *mpw_sitePassword_v2( - MPSiteKey siteKey, const MPPasswordType passwordType); -const char *mpw_encrypt_v2( - MPMasterKey masterKey, const char *plainText); -const char *mpw_decrypt_v2( - MPMasterKey masterKey, const char *cipherText); +const char *mpw_sitePasswordFromTemplate_v2( + MPMasterKey masterKey, MPSiteKey siteKey, const MPResultType resultType, const char *resultParam); +const char *mpw_sitePasswordFromCrypt_v2( + MPMasterKey masterKey, MPSiteKey siteKey, const MPResultType resultType, const char *cipherText); +const char *mpw_sitePasswordFromDerive_v2( + MPMasterKey masterKey, MPSiteKey siteKey, const MPResultType resultType, const char *resultParam); +const char *mpw_siteState_v2( + MPMasterKey masterKey, MPSiteKey siteKey, const MPResultType resultType, const char *state); // Algorithm version overrides. static MPMasterKey mpw_masterKey_v3( @@ -61,7 +63,7 @@ static MPMasterKey mpw_masterKey_v3( // Calculate the master key. trc( "masterKey: scrypt( masterPassword, masterKeySalt, N=%lu, r=%u, p=%u )\n", MP_N, MP_r, MP_p ); - MPMasterKey masterKey = mpw_scrypt( MPMasterKeySize, masterPassword, masterKeySalt, masterKeySaltSize, MP_N, MP_r, MP_p ); + MPMasterKey masterKey = mpw_kdf_scrypt( MPMasterKeySize, masterPassword, masterKeySalt, masterKeySaltSize, MP_N, MP_r, MP_p ); mpw_free( masterKeySalt, masterKeySaltSize ); if (!masterKey) { err( "Could not allocate master key: %s\n", strerror( errno ) ); @@ -73,26 +75,32 @@ static MPMasterKey mpw_masterKey_v3( } static MPSiteKey mpw_siteKey_v3( - MPMasterKey masterKey, const char *siteName, const MPCounterValue siteCounter, + const MPMasterKey masterKey, const char *siteName, const MPCounterValue siteCounter, const MPKeyPurpose keyPurpose, const char *keyContext) { return mpw_siteKey_v2( masterKey, siteName, siteCounter, keyPurpose, keyContext ); } -static const char *mpw_sitePassword_v3( - MPSiteKey siteKey, const MPPasswordType passwordType) { +static const char *mpw_sitePasswordFromTemplate_v3( + MPMasterKey masterKey, MPSiteKey siteKey, const MPResultType resultType, const char *resultParam) { - return mpw_sitePassword_v2( siteKey, passwordType ); + return mpw_sitePasswordFromTemplate_v2( masterKey, siteKey, resultType, resultParam ); } -static const char *mpw_encrypt_v3( - MPMasterKey masterKey, const char *plainText) { +static const char *mpw_sitePasswordFromCrypt_v3( + MPMasterKey masterKey, MPSiteKey siteKey, const MPResultType resultType, const char *cipherText) { - return mpw_encrypt_v2( masterKey, plainText ); + return mpw_sitePasswordFromCrypt_v2( masterKey, siteKey, resultType, cipherText ); } -static const char *mpw_decrypt_v3( - MPMasterKey masterKey, const char *cipherText) { +static const char *mpw_sitePasswordFromDerive_v3( + MPMasterKey masterKey, MPSiteKey siteKey, const MPResultType resultType, const char *resultParam) { - return mpw_decrypt_v2( masterKey, cipherText ); + return mpw_sitePasswordFromDerive_v2( masterKey, siteKey, resultType, resultParam ); +} + +static const char *mpw_siteState_v3( + MPMasterKey masterKey, MPSiteKey siteKey, const MPResultType resultType, const char *state) { + + return mpw_siteState_v2( masterKey, siteKey, resultType, state ); } diff --git a/core/c/mpw-marshall.c b/core/c/mpw-marshall.c index 9ee558fe..303b387a 100644 --- a/core/c/mpw-marshall.c +++ b/core/c/mpw-marshall.c @@ -39,7 +39,7 @@ MPMarshalledUser *mpw_marshall_user( .redacted = true, .avatar = 0, - .defaultType = MPPasswordTypeDefault, + .defaultType = MPResultTypeDefault, .lastUsed = 0, .sites_count = 0, @@ -49,7 +49,7 @@ MPMarshalledUser *mpw_marshall_user( }; MPMarshalledSite *mpw_marshall_site( - MPMarshalledUser *user, const char *siteName, const MPPasswordType passwordType, + MPMarshalledUser *user, const char *siteName, const MPResultType resultType, const MPCounterValue siteCounter, const MPAlgorithmVersion algorithmVersion) { if (!siteName || !mpw_realloc( &user->sites, NULL, sizeof( MPMarshalledSite ) * ++user->sites_count )) @@ -59,7 +59,7 @@ MPMarshalledSite *mpw_marshall_site( *site = (MPMarshalledSite){ .name = strdup( siteName ), .content = NULL, - .type = passwordType, + .type = resultType, .counter = siteCounter, .algorithm = algorithmVersion, @@ -171,13 +171,9 @@ static bool mpw_marshall_write_flat( return false; } - 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 ); - } - else if (site->type & MPSiteFeatureExportContent && site->content && strlen( site->content )) - content = mpw_decrypt( masterKey, site->content, site->algorithm ); + if (site->type & MPResultTypeClassTemplate) + content = mpw_siteResult( masterKey, site->name, site->counter, + MPKeyPurposeAuthentication, NULL, site->type, site->content, site->algorithm ); } else if (site->type & MPSiteFeatureExportContent && site->content && strlen( site->content )) // Redacted @@ -255,13 +251,9 @@ static bool mpw_marshall_write_json( return false; } - 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 ); - } - else if (site->type & MPSiteFeatureExportContent && site->content && strlen( site->content )) - content = mpw_decrypt( masterKey, site->content, site->algorithm ); + if (site->type & MPResultTypeClassTemplate) + content = mpw_siteResult( masterKey, site->name, site->counter, + MPKeyPurposeAuthentication, NULL, site->type, site->content, site->algorithm ); } else if (site->type & MPSiteFeatureExportContent && site->content && strlen( site->content )) // Redacted @@ -294,10 +286,8 @@ static bool mpw_marshall_write_json( if (!user->redacted) { // Clear Text - MPSiteKey siteKey = mpw_siteKey( masterKey, site->name, - MPCounterValueInitial, MPKeyPurposeRecovery, question->keyword, site->algorithm ); - const char *answer = mpw_sitePassword( siteKey, MPPasswordTypeGeneratedPhrase, site->algorithm ); - mpw_free( siteKey, MPSiteKeySize ); + const char *answer = mpw_siteResult( masterKey, site->name, MPCounterValueInitial, + MPKeyPurposeRecovery, question->keyword, MPResultTypeTemplatePhrase, NULL, site->algorithm ); if (answer) json_object_object_add( json_site_question, "answer", json_object_new_string( answer ) ); } @@ -327,10 +317,10 @@ bool mpw_marshall_write( return mpw_marshall_write_flat( out, user, error ); case MPMarshallFormatJSON: return mpw_marshall_write_json( out, user, error ); + default: + *error = (MPMarshallError){ MPMarshallErrorFormat, mpw_str( "Unsupported output format: %u", outFormat ) }; + return false; } - - *error = (MPMarshallError){ MPMarshallErrorFormat, mpw_str( "Unsupported output format: %u", outFormat ) }; - return false; } static MPMarshalledUser *mpw_marshall_read_flat( @@ -344,7 +334,7 @@ static MPMarshalledUser *mpw_marshall_read_flat( unsigned int format = 0, avatar = 0; char *fullName = NULL, *keyID = NULL; MPAlgorithmVersion algorithm = MPAlgorithmVersionCurrent, masterKeyAlgorithm = (MPAlgorithmVersion)-1; - MPPasswordType defaultType = MPPasswordTypeDefault; + MPResultType defaultType = MPResultTypeDefault; bool headerStarted = false, headerEnded = false, importRedacted = false; for (char *endOfLine, *positionInLine = in; (endOfLine = strstr( positionInLine, "\n" )); positionInLine = endOfLine + 1) { @@ -395,11 +385,11 @@ static MPMarshalledUser *mpw_marshall_read_flat( } if (strcmp( headerName, "Default Type" ) == 0) { int value = atoi( headerValue ); - if (!mpw_nameForType( (MPPasswordType)value )) { + if (!mpw_nameForType( (MPResultType)value )) { *error = (MPMarshallError){ MPMarshallErrorIllegal, mpw_str( "Invalid user default type: %s", headerValue ) }; return NULL; } - defaultType = (MPPasswordType)value; + defaultType = (MPResultType)value; } if (strcmp( headerName, "Passwords" ) == 0) importRedacted = strcmp( headerValue, "VISIBLE" ) != 0; @@ -477,7 +467,7 @@ static MPMarshalledUser *mpw_marshall_read_flat( } if (siteName && str_type && str_counter && str_algorithm && str_uses && str_lastUsed) { - MPPasswordType siteType = (MPPasswordType)atoi( str_type ); + MPResultType siteType = (MPResultType)atoi( str_type ); if (!mpw_nameForType( siteType )) { *error = (MPMarshallError){ MPMarshallErrorIllegal, mpw_str( "Invalid site type: %s: %s", siteName, str_type ) }; return NULL; @@ -518,7 +508,8 @@ static MPMarshalledUser *mpw_marshall_read_flat( return NULL; } - site->content = mpw_encrypt( masterKey, siteContent, site->algorithm ); + site->content = mpw_siteState( masterKey, site->name, site->counter, + MPKeyPurposeAuthentication, NULL, site->type, siteContent, site->algorithm ); } else // Redacted @@ -587,7 +578,7 @@ static MPMarshalledUser *mpw_marshall_read_json( return NULL; } MPAlgorithmVersion algorithm = (MPAlgorithmVersion)value; - MPPasswordType defaultType = (MPPasswordType)mpw_get_json_int( json_file, "user.default_type", MPPasswordTypeDefault ); + MPResultType defaultType = (MPResultType)mpw_get_json_int( json_file, "user.default_type", MPResultTypeDefault ); if (!mpw_nameForType( defaultType )) { *error = (MPMarshallError){ MPMarshallErrorIllegal, mpw_str( "Invalid user default type: %u", defaultType ) }; return NULL; @@ -629,7 +620,7 @@ static MPMarshalledUser *mpw_marshall_read_json( return NULL; } MPAlgorithmVersion siteAlgorithm = (MPAlgorithmVersion)value; - MPPasswordType siteType = (MPPasswordType)mpw_get_json_int( json_site.val, "type", user->defaultType ); + MPResultType siteType = (MPResultType)mpw_get_json_int( json_site.val, "type", user->defaultType ); if (!mpw_nameForType( siteType )) { *error = (MPMarshallError){ MPMarshallErrorIllegal, mpw_str( "Invalid site type: %s: %u", siteName, siteType ) }; return NULL; @@ -673,7 +664,8 @@ static MPMarshalledUser *mpw_marshall_read_json( return NULL; } - site->content = mpw_encrypt( masterKey, siteContent, site->algorithm ); + site->content = mpw_siteState( masterKey, site->name, site->counter, + MPKeyPurposeAuthentication, NULL, site->type, siteContent, site->algorithm ); } else // Redacted @@ -699,10 +691,10 @@ MPMarshalledUser *mpw_marshall_read( return mpw_marshall_read_flat( in, masterPassword, error ); case MPMarshallFormatJSON: return mpw_marshall_read_json( in, masterPassword, error ); + default: + *error = (MPMarshallError){ MPMarshallErrorFormat, mpw_str( "Unsupported input format: %u", inFormat ) }; + return NULL; } - - *error = (MPMarshallError){ MPMarshallErrorFormat, mpw_str( "Unsupported input format: %u", inFormat ) }; - return NULL; } const MPMarshallFormat mpw_formatWithName( diff --git a/core/c/mpw-marshall.h b/core/c/mpw-marshall.h index fa6eecae..96b8a4e3 100644 --- a/core/c/mpw-marshall.h +++ b/core/c/mpw-marshall.h @@ -62,7 +62,7 @@ typedef struct MPMarshalledQuestion { typedef struct MPMarshalledSite { const char *name; const char *content; - MPPasswordType type; + MPResultType type; MPCounterValue counter; MPAlgorithmVersion algorithm; @@ -84,7 +84,7 @@ typedef struct MPMarshalledUser { bool redacted; unsigned int avatar; - MPPasswordType defaultType; + MPResultType defaultType; time_t lastUsed; size_t sites_count; @@ -104,7 +104,7 @@ MPMarshalledUser *mpw_marshall_user( const char *fullName, const char *masterPassword, const MPAlgorithmVersion algorithmVersion); MPMarshalledSite *mpw_marshall_site( MPMarshalledUser *user, - const char *siteName, const MPPasswordType passwordType, const MPCounterValue siteCounter, const MPAlgorithmVersion algorithmVersion); + const char *siteName, const MPResultType resultType, const MPCounterValue siteCounter, const MPAlgorithmVersion algorithmVersion); MPMarshalledQuestion *mpw_marshal_question( MPMarshalledSite *site, const char *keyword); bool mpw_marshal_free( diff --git a/core/c/mpw-types.c b/core/c/mpw-types.c index ef9a7659..e8348b15 100644 --- a/core/c/mpw-types.c +++ b/core/c/mpw-types.c @@ -29,28 +29,30 @@ #include "mpw-types.h" #include "mpw-util.h" -const MPPasswordType mpw_typeWithName(const char *typeName) { +const MPResultType mpw_typeWithName(const char *typeName) { // Find what password type is represented by the type letter. if (strlen( typeName ) == 1) { if ('x' == typeName[0]) - return MPPasswordTypeGeneratedMaximum; + return MPResultTypeTemplateMaximum; if ('l' == typeName[0]) - return MPPasswordTypeGeneratedLong; + return MPResultTypeTemplateLong; if ('m' == typeName[0]) - return MPPasswordTypeGeneratedMedium; + return MPResultTypeTemplateMedium; if ('b' == typeName[0]) - return MPPasswordTypeGeneratedBasic; + return MPResultTypeTemplateBasic; if ('s' == typeName[0]) - return MPPasswordTypeGeneratedShort; + return MPResultTypeTemplateShort; if ('i' == typeName[0]) - return MPPasswordTypeGeneratedPIN; + return MPResultTypeTemplatePIN; if ('n' == typeName[0]) - return MPPasswordTypeGeneratedName; + return MPResultTypeTemplateName; if ('P' == typeName[0]) - return MPPasswordTypeStoredPersonal; + return MPResultTypeStatePersonal; if ('D' == typeName[0]) - return MPPasswordTypeStoredDevice; + return MPResultTypeStateDevice; + if ('k' == typeName[0]) + return MPResultTypeDeriveKey; } // Lower-case and trim optionally leading "Generated" string from typeName to standardize it. @@ -64,71 +66,77 @@ const MPPasswordType mpw_typeWithName(const char *typeName) { stdTypeName[stdTypeNameSize] = '\0'; // Find what password type is represented by the type name. - if (strncmp( mpw_nameForType( MPPasswordTypeGeneratedPhrase ), stdTypeName, strlen( stdTypeName ) ) == 0) - return MPPasswordTypeGeneratedPhrase; - if (strncmp( mpw_nameForType( MPPasswordTypeGeneratedMaximum ), stdTypeName, strlen( stdTypeName ) ) == 0) - return MPPasswordTypeGeneratedMaximum; - if (strncmp( mpw_nameForType( MPPasswordTypeGeneratedLong ), stdTypeName, strlen( stdTypeName ) ) == 0) - return MPPasswordTypeGeneratedLong; - if (strncmp( mpw_nameForType( MPPasswordTypeGeneratedMedium ), stdTypeName, strlen( stdTypeName ) ) == 0) - return MPPasswordTypeGeneratedMedium; - if (strncmp( mpw_nameForType( MPPasswordTypeGeneratedBasic ), stdTypeName, strlen( stdTypeName ) ) == 0) - return MPPasswordTypeGeneratedBasic; - if (strncmp( mpw_nameForType( MPPasswordTypeGeneratedShort ), stdTypeName, strlen( stdTypeName ) ) == 0) - return MPPasswordTypeGeneratedShort; - if (strncmp( mpw_nameForType( MPPasswordTypeGeneratedPIN ), stdTypeName, strlen( stdTypeName ) ) == 0) - return MPPasswordTypeGeneratedPIN; - if (strncmp( mpw_nameForType( MPPasswordTypeGeneratedName ), stdTypeName, strlen( stdTypeName ) ) == 0) - return MPPasswordTypeGeneratedName; - if (strncmp( mpw_nameForType( MPPasswordTypeGeneratedPhrase ), stdTypeName, strlen( stdTypeName ) ) == 0) - return MPPasswordTypeGeneratedPhrase; + if (strncmp( mpw_nameForType( MPResultTypeTemplateMaximum ), stdTypeName, strlen( stdTypeName ) ) == 0) + return MPResultTypeTemplateMaximum; + if (strncmp( mpw_nameForType( MPResultTypeTemplateLong ), stdTypeName, strlen( stdTypeName ) ) == 0) + return MPResultTypeTemplateLong; + if (strncmp( mpw_nameForType( MPResultTypeTemplateMedium ), stdTypeName, strlen( stdTypeName ) ) == 0) + return MPResultTypeTemplateMedium; + if (strncmp( mpw_nameForType( MPResultTypeTemplateBasic ), stdTypeName, strlen( stdTypeName ) ) == 0) + return MPResultTypeTemplateBasic; + if (strncmp( mpw_nameForType( MPResultTypeTemplateShort ), stdTypeName, strlen( stdTypeName ) ) == 0) + return MPResultTypeTemplateShort; + if (strncmp( mpw_nameForType( MPResultTypeTemplatePIN ), stdTypeName, strlen( stdTypeName ) ) == 0) + return MPResultTypeTemplatePIN; + if (strncmp( mpw_nameForType( MPResultTypeTemplateName ), stdTypeName, strlen( stdTypeName ) ) == 0) + return MPResultTypeTemplateName; + if (strncmp( mpw_nameForType( MPResultTypeTemplatePhrase ), stdTypeName, strlen( stdTypeName ) ) == 0) + return MPResultTypeTemplatePhrase; + if (strncmp( mpw_nameForType( MPResultTypeStatePersonal ), stdTypeName, strlen( stdTypeName ) ) == 0) + return MPResultTypeStatePersonal; + if (strncmp( mpw_nameForType( MPResultTypeStateDevice ), stdTypeName, strlen( stdTypeName ) ) == 0) + return MPResultTypeStateDevice; + if (strncmp( mpw_nameForType( MPResultTypeDeriveKey ), stdTypeName, strlen( stdTypeName ) ) == 0) + return MPResultTypeDeriveKey; dbg( "Not a generated type name: %s\n", stdTypeName ); - return (MPPasswordType)ERR; + return (MPResultType)ERR; } -const char *mpw_nameForType(MPPasswordType passwordType) { +const char *mpw_nameForType(MPResultType resultType) { - switch (passwordType) { - case MPPasswordTypeGeneratedMaximum: + switch (resultType) { + case MPResultTypeTemplateMaximum: return "maximum"; - case MPPasswordTypeGeneratedLong: + case MPResultTypeTemplateLong: return "long"; - case MPPasswordTypeGeneratedMedium: + case MPResultTypeTemplateMedium: return "medium"; - case MPPasswordTypeGeneratedBasic: + case MPResultTypeTemplateBasic: return "basic"; - case MPPasswordTypeGeneratedShort: + case MPResultTypeTemplateShort: return "short"; - case MPPasswordTypeGeneratedPIN: + case MPResultTypeTemplatePIN: return "pin"; - case MPPasswordTypeGeneratedName: + case MPResultTypeTemplateName: return "name"; - case MPPasswordTypeGeneratedPhrase: + case MPResultTypeTemplatePhrase: return "phrase"; - case MPPasswordTypeStoredPersonal: + case MPResultTypeStatePersonal: return "personal"; - case MPPasswordTypeStoredDevice: + case MPResultTypeStateDevice: return "device"; + case MPResultTypeDeriveKey: + return "key"; default: { - dbg( "Unknown password type: %d\n", passwordType ); + dbg( "Unknown password type: %d\n", resultType ); return NULL; } } } -const char **mpw_templatesForType(MPPasswordType type, size_t *count) { +const char **mpw_templatesForType(MPResultType type, size_t *count) { - if (!(type & MPPasswordTypeClassGenerated)) { + if (!(type & MPResultTypeClassTemplate)) { dbg( "Not a generated type: %d\n", type ); return NULL; } switch (type) { - case MPPasswordTypeGeneratedMaximum: + case MPResultTypeTemplateMaximum: return mpw_alloc_array( count, const char *, "anoxxxxxxxxxxxxxxxxx", "axxxxxxxxxxxxxxxxxno" ); - case MPPasswordTypeGeneratedLong: + case MPResultTypeTemplateLong: return mpw_alloc_array( count, const char *, "CvcvnoCvcvCvcv", "CvcvCvcvnoCvcv", "CvcvCvcvCvcvno", "CvccnoCvcvCvcv", "CvccCvcvnoCvcv", "CvccCvcvCvcvno", @@ -137,22 +145,22 @@ const char **mpw_templatesForType(MPPasswordType type, size_t *count) { "CvccnoCvccCvcv", "CvccCvccnoCvcv", "CvccCvccCvcvno", "CvcvnoCvccCvcc", "CvcvCvccnoCvcc", "CvcvCvccCvccno", "CvccnoCvcvCvcc", "CvccCvcvnoCvcc", "CvccCvcvCvccno" ); - case MPPasswordTypeGeneratedMedium: + case MPResultTypeTemplateMedium: return mpw_alloc_array( count, const char *, "CvcnoCvc", "CvcCvcno" ); - case MPPasswordTypeGeneratedBasic: + case MPResultTypeTemplateBasic: return mpw_alloc_array( count, const char *, "aaanaaan", "aannaaan", "aaannaaa" ); - case MPPasswordTypeGeneratedShort: + case MPResultTypeTemplateShort: return mpw_alloc_array( count, const char *, "Cvcn" ); - case MPPasswordTypeGeneratedPIN: + case MPResultTypeTemplatePIN: return mpw_alloc_array( count, const char *, "nnnn" ); - case MPPasswordTypeGeneratedName: + case MPResultTypeTemplateName: return mpw_alloc_array( count, const char *, "cvccvcvcv" ); - case MPPasswordTypeGeneratedPhrase: + case MPResultTypeTemplatePhrase: return mpw_alloc_array( count, const char *, "cvcc cvc cvccvcv cvc", "cvc cvccvcvcv cvcv", "cv cvccv cvc cvcvccv" ); default: { @@ -162,7 +170,7 @@ const char **mpw_templatesForType(MPPasswordType type, size_t *count) { } } -const char *mpw_templateForType(MPPasswordType type, uint8_t seedByte) { +const char *mpw_templateForType(MPResultType type, uint8_t seedByte) { size_t count = 0; const char **templates = mpw_templatesForType( type, &count ); diff --git a/core/c/mpw-types.h b/core/c/mpw-types.h index c2e0d98f..0a261d3e 100644 --- a/core/c/mpw-types.h +++ b/core/c/mpw-types.h @@ -23,11 +23,11 @@ #include #include -#ifdef NS_ENUM -#define enum(_type, _name) NS_ENUM(_type, _name) -#else +//#ifdef NS_ENUM +//#define enum(_type, _name) NS_ENUM(_type, _name) +//#else #define enum(_type, _name) _type _name; enum -#endif +//#endif //// Types. @@ -47,11 +47,13 @@ typedef enum( uint8_t, MPKeyPurpose ) { }; // bit 4 - 9 -typedef enum( uint16_t, MPPasswordTypeClass ) { - /** Generate the password. */ - MPPasswordTypeClassGenerated = 1 << 4, - /** Store the password. */ - MPPasswordTypeClassStored = 1 << 5, +typedef enum( uint16_t, MPResultTypeClass ) { + /** Use the site key to generate a password from a template. */ + MPResultTypeClassTemplate = 1 << 4, + /** Use the site key to encrypt and decrypt a stateful entity. */ + MPResultTypeClassState = 1 << 5, + /** Use the site key to derive a site-specific object. */ + MPResultTypeClassDerive = 1 << 6, }; // bit 10 - 15 @@ -60,33 +62,38 @@ typedef enum( uint16_t, MPSiteFeature ) { MPSiteFeatureExportContent = 1 << 10, /** Never export content. */ MPSiteFeatureDevicePrivate = 1 << 11, + /** Don't use this as the primary authentication result type. */ + MPSiteFeatureAlternative = 1 << 12, }; -// bit 0-3 | MPPasswordTypeClass | MPSiteFeature -typedef enum( uint32_t, MPPasswordType ) { +// bit 0-3 | MPResultTypeClass | MPSiteFeature +typedef enum( uint32_t, MPResultType ) { /** pg^VMAUBk5x3p%HP%i4= */ - MPPasswordTypeGeneratedMaximum = 0x0 | MPPasswordTypeClassGenerated | 0x0, + MPResultTypeTemplateMaximum = 0x0 | MPResultTypeClassTemplate | 0x0, /** BiroYena8:Kixa */ - MPPasswordTypeGeneratedLong = 0x1 | MPPasswordTypeClassGenerated | 0x0, + MPResultTypeTemplateLong = 0x1 | MPResultTypeClassTemplate | 0x0, /** BirSuj0- */ - MPPasswordTypeGeneratedMedium = 0x2 | MPPasswordTypeClassGenerated | 0x0, + MPResultTypeTemplateMedium = 0x2 | MPResultTypeClassTemplate | 0x0, /** pO98MoD0 */ - MPPasswordTypeGeneratedBasic = 0x4 | MPPasswordTypeClassGenerated | 0x0, + MPResultTypeTemplateBasic = 0x4 | MPResultTypeClassTemplate | 0x0, /** Bir8 */ - MPPasswordTypeGeneratedShort = 0x3 | MPPasswordTypeClassGenerated | 0x0, + MPResultTypeTemplateShort = 0x3 | MPResultTypeClassTemplate | 0x0, /** 2798 */ - MPPasswordTypeGeneratedPIN = 0x5 | MPPasswordTypeClassGenerated | 0x0, + MPResultTypeTemplatePIN = 0x5 | MPResultTypeClassTemplate | 0x0, /** birsujano */ - MPPasswordTypeGeneratedName = 0xE | MPPasswordTypeClassGenerated | 0x0, + MPResultTypeTemplateName = 0xE | MPResultTypeClassTemplate | 0x0, /** bir yennoquce fefi */ - MPPasswordTypeGeneratedPhrase = 0xF | MPPasswordTypeClassGenerated | 0x0, + MPResultTypeTemplatePhrase = 0xF | MPResultTypeClassTemplate | 0x0, /** Custom saved password. */ - MPPasswordTypeStoredPersonal = 0x0 | MPPasswordTypeClassStored | MPSiteFeatureExportContent, + MPResultTypeStatePersonal = 0x0 | MPResultTypeClassState | MPSiteFeatureExportContent, /** Custom saved password that should not be exported from the device. */ - MPPasswordTypeStoredDevice = 0x1 | MPPasswordTypeClassStored | MPSiteFeatureDevicePrivate, + MPResultTypeStateDevice = 0x1 | MPResultTypeClassState | MPSiteFeatureDevicePrivate, - MPPasswordTypeDefault = MPPasswordTypeGeneratedLong, + /** Derive a unique binary key. */ + MPResultTypeDeriveKey = 0x0 | MPResultTypeClassDerive | MPSiteFeatureAlternative, + + MPResultTypeDefault = MPResultTypeTemplateLong, }; typedef enum ( uint32_t, MPCounterValue ) { @@ -118,11 +125,11 @@ const char *mpw_scopeForPurpose(MPKeyPurpose purpose); /** * @return The password type represented by the given name. */ -const MPPasswordType mpw_typeWithName(const char *typeName); +const MPResultType mpw_typeWithName(const char *typeName); /** * @return The standard name for the given password type. */ -const char *mpw_nameForType(MPPasswordType passwordType); +const char *mpw_nameForType(MPResultType resultType); /** * @return A newly allocated array of internal strings that express the templates to use for the given type. @@ -130,12 +137,12 @@ const char *mpw_nameForType(MPPasswordType passwordType); * 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(MPPasswordType type, size_t *count); +const char **mpw_templatesForType(MPResultType 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(MPPasswordType type, uint8_t seedByte); +const char *mpw_templateForType(MPResultType 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 53d155ee..40e7b255 100644 --- a/core/c/mpw-util.c +++ b/core/c/mpw-util.c @@ -18,6 +18,7 @@ #include #include +#include #if MPW_COLOR #include @@ -32,6 +33,7 @@ #include "sodium.h" #ifdef SODIUM_LIBRARY_MINIMAL #include "crypto_stream_aes128ctr.h" +#include "crypto_kdf_blake2b.h" #endif #endif @@ -122,7 +124,7 @@ bool mpw_free_string(const char *string) { return string && mpw_free( string, strlen( string ) ); } -uint8_t const *mpw_scrypt(const size_t keySize, const char *secret, const uint8_t *salt, const size_t saltSize, +uint8_t const *mpw_kdf_scrypt(const size_t keySize, const char *secret, const uint8_t *salt, const size_t saltSize, uint64_t N, uint32_t r, uint32_t p) { if (!secret || !salt) @@ -149,7 +151,49 @@ uint8_t const *mpw_scrypt(const size_t keySize, const char *secret, const uint8_ return key; } -uint8_t const *mpw_hmac_sha256(const uint8_t *key, const size_t keySize, const uint8_t *message, const size_t messageSize) { +uint8_t const *mpw_kdf_blake2b(const size_t subkeySize, const uint8_t *key, const size_t keySize, + const uint8_t *context, const size_t contextSize, const uint64_t id, const char *personal) { + + if (!key || !keySize || !subkeySize) { + errno = EINVAL; + return NULL; + } + + uint8_t *subkey = malloc( subkeySize ); + if (!subkey) + return NULL; + +#if HAS_SODIUM + if (personal && strlen( personal ) > crypto_generichash_blake2b_PERSONALBYTES) { + errno = EINVAL; + free( subkey ); + return NULL; + } + + uint8_t saltBuf[crypto_generichash_blake2b_SALTBYTES]; + bzero( saltBuf, sizeof saltBuf ); + if (id) { + uint64_t id_n = htonll( id ); + memcpy( saltBuf, &id_n, sizeof id_n ); + } + + uint8_t personalBuf[crypto_generichash_blake2b_PERSONALBYTES]; + bzero( personalBuf, sizeof saltBuf ); + if (personal && strlen( personal )) + memcpy( personalBuf, personal, strlen( personal ) ); + + if (crypto_generichash_blake2b_salt_personal( subkey, subkeySize, context, contextSize, key, keySize, saltBuf, personalBuf ) != 0) { + mpw_free( subkey, subkeySize ); + return NULL; + } +#else +#error No crypto support for mpw_scrypt. +#endif + + return subkey; +} + +uint8_t const *mpw_hash_hmac_sha256(const uint8_t *key, const size_t keySize, const uint8_t *message, const size_t messageSize) { if (!key || !keySize || !message || !messageSize) return NULL; @@ -330,7 +374,8 @@ const char *mpw_identicon(const char *fullName, const char *masterPassword) { "♨", "♩", "♪", "♫", "⚐", "⚑", "⚔", "⚖", "⚙", "⚠", "⌘", "⏎", "✄", "✆", "✈", "✉", "✌" }; - const uint8_t *identiconSeed = mpw_hmac_sha256( (const uint8_t *)masterPassword, strlen( masterPassword ), (const uint8_t *)fullName, + const uint8_t *identiconSeed = mpw_hash_hmac_sha256( (const uint8_t *)masterPassword, strlen( masterPassword ), + (const uint8_t *)fullName, strlen( fullName ) ); if (!identiconSeed) return NULL; diff --git a/core/c/mpw-util.h b/core/c/mpw-util.h index 740661ac..50d4bb17 100644 --- a/core/c/mpw-util.h +++ b/core/c/mpw-util.h @@ -141,12 +141,17 @@ bool mpw_free_string( /** Derive a key from the given secret and salt using the scrypt KDF. * @return A new keySize allocated buffer containing the key. */ -uint8_t const *mpw_scrypt( +uint8_t const *mpw_kdf_scrypt( const size_t keySize, const char *secret, const uint8_t *salt, const size_t saltSize, uint64_t N, uint32_t r, uint32_t p); +/** Derive a subkey from the given key. + * @return A new keySize allocated buffer containing the key. */ +uint8_t const *mpw_kdf_blake2b( + const size_t subkeySize, const uint8_t *key, const size_t keySize, + const uint8_t *context, const size_t contextSize, const uint64_t id, const char *personal); /** Calculate the MAC for the given message with the given key using SHA256-HMAC. * @return A new 32-byte allocated buffer containing the MAC. */ -uint8_t const *mpw_hmac_sha256( +uint8_t const *mpw_hash_hmac_sha256( const uint8_t *key, const size_t keySize, const uint8_t *salt, const size_t saltSize); /** Encrypt a plainBuf with the given key using AES-128-CBC. * @return A new bufSize allocated buffer containing the cipherBuf. */ diff --git a/core/java/tests/src/main/resources/mpw_tests.xml b/core/java/tests/src/main/resources/mpw_tests.xml index ada559ab..36465d8b 100644 --- a/core/java/tests/src/main/resources/mpw_tests.xml +++ b/core/java/tests/src/main/resources/mpw_tests.xml @@ -7,7 +7,7 @@ 98EEF4D1DF46D849574A82A03C3177056B15DFFCA29BB3899DE4628453675302 masterpasswordapp.com 1 - GeneratedLong + GeneratedLong Authentication @@ -33,12 +33,12 @@ Identification - GeneratedName + GeneratedName wohzaqage Recovery - GeneratedPhrase + GeneratedPhrase xin diyjiqoja hubu @@ -46,31 +46,31 @@ 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 @@ -99,12 +99,12 @@ Identification - GeneratedName + GeneratedName wohzaqage Recovery - GeneratedPhrase + GeneratedPhrase xin diyjiqoja hubu @@ -112,31 +112,31 @@ 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 @@ -165,12 +165,12 @@ Identification - GeneratedName + GeneratedName wohzaqage Recovery - GeneratedPhrase + GeneratedPhrase xin diyjiqoja hubu @@ -178,31 +178,31 @@ 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 @@ -231,12 +231,12 @@ Identification - GeneratedName + GeneratedName lozwajave Recovery - GeneratedPhrase + GeneratedPhrase miy lirfijoja dubu @@ -244,31 +244,31 @@ 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-independent/cli-c/cli/mpw-bench.c b/platform-independent/cli-c/cli/mpw-bench.c index 1e9abeba..3cc62422 100644 --- a/platform-independent/cli-c/cli/mpw-bench.c +++ b/platform-independent/cli-c/cli/mpw-bench.c @@ -50,7 +50,7 @@ int main(int argc, char *const argv[]) { const char *masterPassword = "banana colored duckling"; const char *siteName = "masterpasswordapp.com"; const MPCounterValue siteCounter = MPCounterValueDefault; - const MPPasswordType passwordType = MPPasswordTypeDefault; + const MPResultType resultType = MPResultTypeDefault; const MPKeyPurpose keyPurpose = MPKeyPurposeAuthentication; const char *keyContext = NULL; struct timeval startTime; @@ -69,7 +69,7 @@ int main(int argc, char *const argv[]) { } mpw_getTime( &startTime ); for (int i = 1; i <= iterations; ++i) { - free( (void *)mpw_hmac_sha256( masterKey, MPMasterKeySize, sitePasswordInfo, 128 ) ); + free( (void *)mpw_hash_hmac_sha256( masterKey, MPMasterKeySize, sitePasswordInfo, 128 ) ); if (modff(100.f * i / iterations, &percent) == 0) fprintf( stderr, "\rhmac-sha-256: iteration %d / %d (%.0f%%)..", i, iterations, percent ); @@ -113,12 +113,9 @@ int main(int argc, char *const argv[]) { break; } - MPSiteKey siteKey = mpw_siteKey( - masterKey, siteName, siteCounter, keyPurpose, keyContext, MPAlgorithmVersionCurrent ); - free( (void *)mpw_sitePassword( - siteKey, passwordType, MPAlgorithmVersionCurrent ) ); + free( (void *)mpw_siteResult( + masterKey, siteName, siteCounter, keyPurpose, keyContext, resultType, NULL, MPAlgorithmVersionCurrent ) ); free( (void *)masterKey ); - free( (void *)siteKey ); if (modff(100.f * i / iterations, &percent) == 0) fprintf( stderr, "\rmpw: iteration %d / %d (%.0f%%)..", i, iterations, percent ); diff --git a/platform-independent/cli-c/cli/mpw-cli.c b/platform-independent/cli-c/cli/mpw-cli.c index 44b338e5..c5cbc42d 100644 --- a/platform-independent/cli-c/cli/mpw-cli.c +++ b/platform-independent/cli-c/cli/mpw-cli.c @@ -47,7 +47,8 @@ static void usage() { " i, pin | 4 numbers.\n" " n, name | 9 letter name.\n" " p, phrase | 20 character sentence.\n" - " P, personal | saved personal password (see -s).\n\n" ); + " K, key | encryption key (set key size -s bits).\n" + " P, personal | saved personal password (save with -s pw).\n\n" ); inf( "" " -c counter The value of the counter.\n" " Defaults to 1.\n\n" ); @@ -56,7 +57,8 @@ static void usage() { " Defaults to %s in env or %d.\n\n", MPAlgorithmVersionFirst, MPAlgorithmVersionLast, MP_ENV_algorithm, MPAlgorithmVersionCurrent ); inf( "" - " -s value The value to save for -t P or -p i.\n\n" ); + " -s value The value to save for -t P or -p i.\n" + " The size of they key to generate for -t K, in bits (eg. 256).\n\n" ); inf( "" " -p purpose The purpose of the generated token.\n" " Defaults to 'auth'.\n" @@ -150,9 +152,9 @@ static char *mpw_path(const char *prefix, const char *extension) { int main(int argc, char *const argv[]) { // Master Password defaults. - const char *fullName = NULL, *masterPassword = NULL, *siteName = NULL, *saveValue = NULL, *keyContext = NULL; + const char *fullName = NULL, *masterPassword = NULL, *siteName = NULL, *resultParam = NULL, *keyContext = NULL; MPCounterValue siteCounter = MPCounterValueDefault; - MPPasswordType passwordType = MPPasswordTypeDefault; + MPResultType resultType = MPResultTypeDefault; MPKeyPurpose keyPurpose = MPKeyPurposeAuthentication; MPAlgorithmVersion algorithmVersion = MPAlgorithmVersionCurrent; MPMarshallFormat sitesFormat = MPMarshallFormatDefault; @@ -160,13 +162,13 @@ int main(int argc, char *const argv[]) { // Read the environment. const char *fullNameArg = NULL, *masterPasswordArg = NULL, *siteNameArg = NULL; - const char *passwordTypeArg = NULL, *siteCounterArg = NULL, *algorithmVersionArg = NULL, *saveValueArg = NULL; + const char *resultTypeArg = NULL, *resultParamArg = NULL, *siteCounterArg = NULL, *algorithmVersionArg = NULL; const char *keyPurposeArg = NULL, *keyContextArg = NULL, *sitesFormatArg = NULL, *sitesRedactedArg = NULL; fullNameArg = mpw_getenv( MP_ENV_fullName ); algorithmVersionArg = mpw_getenv( MP_ENV_algorithm ); // Read the command-line options. - for (int opt; (opt = getopt( argc, argv, "u:U:P:t:c:a:s:p:C:f:F:R:vqh" )) != EOF;) + for (int opt; (opt = getopt( argc, argv, "u:U:M:t:P:c:a:s:p:C:f:F:R:vqh" )) != EOF;) switch (opt) { case 'u': fullNameArg = optarg && strlen( optarg )? strdup( optarg ): NULL; @@ -176,12 +178,15 @@ int main(int argc, char *const argv[]) { fullNameArg = optarg && strlen( optarg )? strdup( optarg ): NULL; allowPasswordUpdate = true; break; - case 'P': + case 'M': // Passing your master password via the command-line is insecure. Testing purposes only. masterPasswordArg = optarg && strlen( optarg )? strdup( optarg ): NULL; break; case 't': - passwordTypeArg = optarg && strlen( optarg )? strdup( optarg ): NULL; + resultTypeArg = optarg && strlen( optarg )? strdup( optarg ): NULL; + break; + case 'P': + resultParamArg = optarg && strlen( optarg )? strdup( optarg ): NULL; break; case 'c': siteCounterArg = optarg && strlen( optarg )? strdup( optarg ): NULL; @@ -189,9 +194,6 @@ int main(int argc, char *const argv[]) { case 'a': algorithmVersionArg = optarg && strlen( optarg )? strdup( optarg ): NULL; break; - case 's': - saveValueArg = optarg && strlen( optarg )? strdup( optarg ): NULL; - break; case 'p': keyPurposeArg = optarg && strlen( optarg )? strdup( optarg ): NULL; break; @@ -342,7 +344,7 @@ int main(int argc, char *const argv[]) { fullName = strdup( user->fullName ); masterPassword = strdup( user->masterPassword ); algorithmVersion = user->algorithm; - passwordType = user->defaultType; + resultType = user->defaultType; sitesRedacted = user->redacted; if (!sitesRedacted && !sitesRedactedArg) @@ -355,8 +357,8 @@ int main(int argc, char *const argv[]) { continue; } - mpw_free_string( saveValue ); - passwordType = site->type; + mpw_free_string( resultParam ); + resultType = site->type; siteCounter = site->counter; algorithmVersion = site->algorithm; break; @@ -383,10 +385,6 @@ int main(int argc, char *const argv[]) { } algorithmVersion = (MPAlgorithmVersion)algorithmVersionInt; } - if (saveValueArg) { - mpw_free_string( saveValue ); - saveValue = strdup( saveValueArg ); - } if (keyPurposeArg) { keyPurpose = mpw_purposeWithName( keyPurposeArg ); if (ERR == (int)keyPurpose) { @@ -399,23 +397,27 @@ int main(int argc, char *const argv[]) { case MPKeyPurposeAuthentication: break; case MPKeyPurposeIdentification: { - passwordType = MPPasswordTypeGeneratedName; + resultType = MPResultTypeTemplateName; purposeResult = "login"; break; } case MPKeyPurposeRecovery: { - passwordType = MPPasswordTypeGeneratedPhrase; + resultType = MPResultTypeTemplatePhrase; purposeResult = "answer"; break; } } - if (passwordTypeArg) { - passwordType = mpw_typeWithName( passwordTypeArg ); - if (ERR == (int)passwordType) { - ftl( "Invalid type: %s\n", passwordTypeArg ); + if (resultTypeArg) { + resultType = mpw_typeWithName( resultTypeArg ); + if (ERR == (int)resultType) { + ftl( "Invalid type: %s\n", resultTypeArg ); return EX_USAGE; } } + if (resultParamArg) { + mpw_free_string( resultParam ); + resultParam = strdup( resultParamArg ); + } if (keyContextArg) { mpw_free_string( keyContext ); keyContext = strdup( keyContextArg ); @@ -423,10 +425,10 @@ int main(int argc, char *const argv[]) { mpw_free_string( fullNameArg ); mpw_free_string( masterPasswordArg ); mpw_free_string( siteNameArg ); - mpw_free_string( passwordTypeArg ); + mpw_free_string( resultTypeArg ); + mpw_free_string( resultParamArg ); mpw_free_string( siteCounterArg ); mpw_free_string( algorithmVersionArg ); - mpw_free_string( saveValueArg ); mpw_free_string( keyPurposeArg ); mpw_free_string( keyContextArg ); mpw_free_string( sitesFormatArg ); @@ -444,10 +446,10 @@ int main(int argc, char *const argv[]) { dbg( "sitesPath : %s\n", sitesPath ); dbg( "siteName : %s\n", siteName ); dbg( "siteCounter : %u\n", siteCounter ); - dbg( "saveValue : %s\n", saveValue ); + dbg( "resultType : %s (%u)\n", mpw_nameForType( resultType ), resultType ); + dbg( "resultParam : %s\n", resultParam ); dbg( "keyPurpose : %s (%u)\n", mpw_nameForPurpose( keyPurpose ), keyPurpose ); dbg( "keyContext : %s\n", keyContext ); - dbg( "passwordType : %s (%u)\n", mpw_nameForType( passwordType ), passwordType ); dbg( "algorithmVersion : %u\n", algorithmVersion ); dbg( "-----------------\n\n" ); inf( "%s's %s for %s:\n[ %s ]: ", fullName, purposeResult, siteName, identicon ); @@ -469,71 +471,57 @@ int main(int argc, char *const argv[]) { if (keyPurpose == MPKeyPurposeIdentification && site && !site->loginGenerated && site->loginName) fprintf( stdout, "%s\n", site->loginName ); - else if (passwordType & MPPasswordTypeClassGenerated) { - MPSiteKey siteKey = mpw_siteKey( masterKey, siteName, siteCounter, keyPurpose, keyContext, algorithmVersion ); - const char *sitePassword = mpw_sitePassword( siteKey, passwordType, algorithmVersion ); - mpw_free( siteKey, MPSiteKeySize ); - if (!sitePassword) { - ftl( "Couldn't derive site password.\n" ); + else if (resultParam && site && resultType & MPResultTypeClassState) { + mpw_free_string( site->content ); + if (!(site->content = mpw_siteState( masterKey, siteName, siteCounter, + keyPurpose, keyContext, resultType, resultParam, algorithmVersion ))) { + ftl( "Couldn't encrypt site content.\n" ); mpw_free( masterKey, MPMasterKeySize ); return EX_SOFTWARE; } - fprintf( stdout, "%s\n", sitePassword ); - mpw_free_string( sitePassword ); + inf( "saved.\n" ); } - else { - const char *content = NULL; - if (saveValue) { - content = strdup( saveValue ); - if (site) { - // TODO: Doesn't save content for newly created sites. - mpw_free_string( site->content ); - if (!(site->content = mpw_encrypt( masterKey, saveValue, algorithmVersion ))) - err( "Couldn't encrypt site content.\n" ); - } + if (!resultParam && site && site->content && resultType & MPResultTypeClassState) + resultParam = strdup( site->content ); + const char *siteResult = mpw_siteResult( masterKey, siteName, siteCounter, + keyPurpose, keyContext, resultType, resultParam, algorithmVersion ); + if (!siteResult) { + ftl( "Couldn't generate site result.\n" ); + mpw_free( masterKey, MPMasterKeySize ); + return EX_SOFTWARE; } - else if (site && site->content) { - content = mpw_decrypt( masterKey, site->content, algorithmVersion ); - if (!content) { - ftl( "Couldn't decrypt site content.\n" ); - mpw_free( masterKey, MPMasterKeySize ); - return EX_SOFTWARE; - } - } - - fprintf( stdout, "%s\n", content ); - mpw_free_string( content ); + fprintf( stdout, "%s\n", siteResult ); + mpw_free_string( siteResult ); } - if (site && site->url) inf( "See: %s\n", site->url ); mpw_free( masterKey, MPMasterKeySize ); mpw_free_string( siteName ); - mpw_free_string( saveValue ); + mpw_free_string( resultParam ); mpw_free_string( keyContext ); // Update the mpsites file. if (user) { // TODO: Move this up above the summary and replace the mpw lvars by user/site accessors. - if (keyPurpose == MPKeyPurposeAuthentication) { + if (keyPurpose == MPKeyPurposeAuthentication && !(resultType & MPSiteFeatureAlternative)) { if (!site) - site = mpw_marshall_site( user, siteName, passwordType, siteCounter, algorithmVersion ); + site = mpw_marshall_site( user, siteName, resultType, siteCounter, algorithmVersion ); else { - site->type = passwordType; + site->type = resultType; site->counter = siteCounter; site->algorithm = algorithmVersion; } } else if (keyPurpose == MPKeyPurposeIdentification && site) { - // TODO: We're not persisting the passwordType of the generated login - if (passwordType & MPPasswordTypeClassGenerated) + // TODO: We're not persisting the resultType of the generated login + if (resultType & MPResultTypeClassTemplate) site->loginGenerated = true; } else if (keyPurpose == MPKeyPurposeRecovery && site && keyContext) { - // TODO: We're not persisting the passwordType of the recovery question + // TODO: We're not persisting the resultType of the recovery question MPMarshalledQuestion *question = NULL; for (size_t q = 0; q < site->questions_count; ++q) { question = &site->questions[q]; diff --git a/platform-independent/cli-c/cli/mpw-tests.c b/platform-independent/cli-c/cli/mpw-tests.c index d167605c..eada047c 100644 --- a/platform-independent/cli-c/cli/mpw-tests.c +++ b/platform-independent/cli-c/cli/mpw-tests.c @@ -30,13 +30,13 @@ int main(int argc, char *const argv[]) { xmlChar *keyID = mpw_xmlTestCaseString( testCase, "keyID" ); xmlChar *siteName = mpw_xmlTestCaseString( testCase, "siteName" ); MPCounterValue siteCounter = (MPCounterValue)mpw_xmlTestCaseInteger( testCase, "siteCounter" ); - xmlChar *passwordTypeString = mpw_xmlTestCaseString( testCase, "passwordType" ); + xmlChar *resultTypeString = mpw_xmlTestCaseString( testCase, "resultType" ); xmlChar *keyPurposeString = mpw_xmlTestCaseString( testCase, "keyPurpose" ); xmlChar *keyContext = mpw_xmlTestCaseString( testCase, "keyContext" ); xmlChar *result = mpw_xmlTestCaseString( testCase, "result" ); - MPPasswordType siteType = mpw_typeWithName( (char *)passwordTypeString ); - MPKeyPurpose siteVariant = mpw_purposeWithName( (char *)keyPurposeString ); + MPResultType resultType = mpw_typeWithName( (char *)resultTypeString ); + MPKeyPurpose keyPurpose = mpw_purposeWithName( (char *)keyPurposeString ); // Run the test case. fprintf( stdout, "test case %s... ", id ); @@ -54,12 +54,9 @@ int main(int argc, char *const argv[]) { } // 2. calculate the site password. - MPSiteKey siteKey = mpw_siteKey( - masterKey, (char *)siteName, siteCounter, siteVariant, (char *)keyContext, algorithm ); - const char *sitePassword = mpw_sitePassword( - siteKey, siteType, algorithm ); + const char *sitePassword = mpw_siteResult( + masterKey, (char *)siteName, siteCounter, keyPurpose, (char *)keyContext, resultType, NULL, algorithm ); mpw_free( masterKey, MPMasterKeySize ); - mpw_free( siteKey, MPSiteKeySize ); if (!sitePassword) { ftl( "Couldn't derive site password.\n" ); continue; @@ -81,7 +78,7 @@ int main(int argc, char *const argv[]) { xmlFree( masterPassword ); xmlFree( keyID ); xmlFree( siteName ); - xmlFree( passwordTypeString ); + xmlFree( resultTypeString ); xmlFree( keyPurposeString ); xmlFree( keyContext ); xmlFree( result ); diff --git a/platform-independent/cli-c/distribute b/platform-independent/cli-c/distribute index b232d3cd..befe2e88 100755 --- a/platform-independent/cli-c/distribute +++ b/platform-independent/cli-c/distribute @@ -5,7 +5,6 @@ cd "${BASH_SOURCE%/*}" tag=$(git describe --match '*-cli*') commit=$(git describe --long --dirty --match '*-cli*') [[ $commit != *-dirty ]] || { echo >&2 "Tree is dirty, first commit any changes."; exit 1; } -git show --show-signature --pretty=format:%H --quiet "$tag" > VERSION mpwArchive=mpw-$commit.tar.gz [[ -e $mpwArchive ]] && echo >&2 "WARNING: $mpwArchive already exists. Will overwrite." @@ -15,6 +14,7 @@ echo "Cleaning .." ( git clean -ffdx . && cd core && git clean -ffdx . ) echo "Creating archive $mpwArchive .." +git show --show-signature --pretty=format:%H --quiet "$tag" > VERSION git ls-files -z . | xargs -0 tar -Lcvzf "$mpwArchive" echo "Creating archive signature $mpwArchive.sig .."