passwordType -> resultType, add derived class and key type.
This commit is contained in:
parent
b1985a2bf2
commit
4f7c28563d
@ -72,69 +72,98 @@ MPSiteKey mpw_siteKey(
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *mpw_sitePassword(
|
const char *mpw_siteResult(
|
||||||
MPSiteKey siteKey, const MPPasswordType passwordType, const MPAlgorithmVersion algorithmVersion) {
|
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 );
|
MPSiteKey siteKey = mpw_siteKey_v0( masterKey, siteName, siteCounter, keyPurpose, keyContext );
|
||||||
trc( "passwordType: %d (%s)\n", passwordType, mpw_nameForType( passwordType ) );
|
|
||||||
if (!siteKey)
|
if (!siteKey)
|
||||||
return NULL;
|
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) {
|
switch (algorithmVersion) {
|
||||||
case MPAlgorithmVersion0:
|
case MPAlgorithmVersion0:
|
||||||
return mpw_sitePassword_v0( siteKey, passwordType );
|
return mpw_sitePasswordFromTemplate_v0( masterKey, siteKey, resultType, resultParam );
|
||||||
case MPAlgorithmVersion1:
|
case MPAlgorithmVersion1:
|
||||||
return mpw_sitePassword_v1( siteKey, passwordType );
|
return mpw_sitePasswordFromTemplate_v1( masterKey, siteKey, resultType, resultParam );
|
||||||
case MPAlgorithmVersion2:
|
case MPAlgorithmVersion2:
|
||||||
return mpw_sitePassword_v2( siteKey, passwordType );
|
return mpw_sitePasswordFromTemplate_v2( masterKey, siteKey, resultType, resultParam );
|
||||||
case MPAlgorithmVersion3:
|
case MPAlgorithmVersion3:
|
||||||
return mpw_sitePassword_v3( siteKey, passwordType );
|
return mpw_sitePasswordFromTemplate_v3( masterKey, siteKey, resultType, resultParam );
|
||||||
default:
|
default:
|
||||||
err( "Unsupported version: %d\n", algorithmVersion );
|
err( "Unsupported version: %d\n", algorithmVersion );
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (resultType & MPResultTypeClassState) {
|
||||||
const char *mpw_encrypt(
|
|
||||||
MPMasterKey masterKey, const char *plainText, const MPAlgorithmVersion algorithmVersion) {
|
|
||||||
|
|
||||||
trc( "-- mpw_encrypt (algorithm: %u)\n", algorithmVersion );
|
|
||||||
trc( "plainText: %s = %s\n", plainText, mpw_hex( plainText, sizeof( plainText ) ) );
|
|
||||||
if (!masterKey || !plainText)
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
switch (algorithmVersion) {
|
switch (algorithmVersion) {
|
||||||
case MPAlgorithmVersion0:
|
case MPAlgorithmVersion0:
|
||||||
return mpw_encrypt_v0( masterKey, plainText );
|
return mpw_sitePasswordFromCrypt_v0( masterKey, siteKey, resultType, resultParam );
|
||||||
case MPAlgorithmVersion1:
|
case MPAlgorithmVersion1:
|
||||||
return mpw_encrypt_v1( masterKey, plainText );
|
return mpw_sitePasswordFromCrypt_v1( masterKey, siteKey, resultType, resultParam );
|
||||||
case MPAlgorithmVersion2:
|
case MPAlgorithmVersion2:
|
||||||
return mpw_encrypt_v2( masterKey, plainText );
|
return mpw_sitePasswordFromCrypt_v2( masterKey, siteKey, resultType, resultParam );
|
||||||
case MPAlgorithmVersion3:
|
case MPAlgorithmVersion3:
|
||||||
return mpw_encrypt_v3( masterKey, plainText );
|
return mpw_sitePasswordFromCrypt_v3( masterKey, siteKey, resultType, resultParam );
|
||||||
default:
|
default:
|
||||||
err( "Unsupported version: %d\n", algorithmVersion );
|
err( "Unsupported version: %d\n", algorithmVersion );
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
else if (resultType & MPResultTypeClassDerive) {
|
||||||
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) {
|
switch (algorithmVersion) {
|
||||||
case MPAlgorithmVersion0:
|
case MPAlgorithmVersion0:
|
||||||
return mpw_decrypt_v0( masterKey, cipherText );
|
return mpw_sitePasswordFromDerive_v0( masterKey, siteKey, resultType, resultParam );
|
||||||
case MPAlgorithmVersion1:
|
case MPAlgorithmVersion1:
|
||||||
return mpw_decrypt_v1( masterKey, cipherText );
|
return mpw_sitePasswordFromDerive_v1( masterKey, siteKey, resultType, resultParam );
|
||||||
case MPAlgorithmVersion2:
|
case MPAlgorithmVersion2:
|
||||||
return mpw_decrypt_v2( masterKey, cipherText );
|
return mpw_sitePasswordFromDerive_v2( masterKey, siteKey, resultType, resultParam );
|
||||||
case MPAlgorithmVersion3:
|
case MPAlgorithmVersion3:
|
||||||
return mpw_decrypt_v3( masterKey, cipherText );
|
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_siteState(
|
||||||
|
MPMasterKey masterKey, const char *siteName, const MPCounterValue siteCounter,
|
||||||
|
const MPKeyPurpose keyPurpose, const char *keyContext,
|
||||||
|
const MPResultType resultType, const char *state,
|
||||||
|
const MPAlgorithmVersion algorithmVersion) {
|
||||||
|
|
||||||
|
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_siteState_v0( masterKey, siteKey, resultType, state );
|
||||||
|
case MPAlgorithmVersion1:
|
||||||
|
return mpw_siteState_v1( masterKey, siteKey, resultType, state );
|
||||||
|
case MPAlgorithmVersion2:
|
||||||
|
return mpw_siteState_v2( masterKey, siteKey, resultType, state );
|
||||||
|
case MPAlgorithmVersion3:
|
||||||
|
return mpw_siteState_v3( masterKey, siteKey, resultType, state );
|
||||||
default:
|
default:
|
||||||
err( "Unsupported version: %d\n", algorithmVersion );
|
err( "Unsupported version: %d\n", algorithmVersion );
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -50,17 +50,18 @@ MPSiteKey mpw_siteKey(
|
|||||||
|
|
||||||
/** Encode a password for the site from the given site key.
|
/** Encode a password for the site from the given site key.
|
||||||
* @return A newly allocated string or NULL if an error occurred. */
|
* @return A newly allocated string or NULL if an error occurred. */
|
||||||
const char *mpw_sitePassword(
|
const char *mpw_siteResult(
|
||||||
MPSiteKey siteKey, const MPPasswordType passwordType, const MPAlgorithmVersion algorithmVersion);
|
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.
|
/** Perform symmetric encryption on a secret token's plainText.
|
||||||
* @return The newly allocated cipherText of the secret token encrypted by the masterKey. */
|
* @return The newly allocated cipherText of the secret token encrypted by the masterKey. */
|
||||||
const char *mpw_encrypt(
|
const char *mpw_siteState(
|
||||||
MPMasterKey masterKey, const char *plainText, const MPAlgorithmVersion algorithmVersion);
|
MPMasterKey masterKey, const char *siteName, const MPCounterValue siteCounter,
|
||||||
|
const MPKeyPurpose keyPurpose, const char *keyContext,
|
||||||
/** Perform symmetric decryption on a secret token's cipherText.
|
const MPResultType resultType, const char *state,
|
||||||
* @return The newly allocated plainText of the secret token decrypted by the masterKey. */
|
const MPAlgorithmVersion algorithmVersion);
|
||||||
const char *mpw_decrypt(
|
|
||||||
MPMasterKey masterKey, const char *cipherText, const MPAlgorithmVersion algorithmVersion);
|
|
||||||
|
|
||||||
#endif // _MPW_ALGORITHM_H
|
#endif // _MPW_ALGORITHM_H
|
||||||
|
@ -29,7 +29,7 @@
|
|||||||
#define MP_p 2U
|
#define MP_p 2U
|
||||||
|
|
||||||
// Algorithm version helpers.
|
// 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;
|
size_t count = 0;
|
||||||
const char **templates = mpw_templatesForType( type, &count );
|
const char **templates = mpw_templatesForType( type, &count );
|
||||||
@ -70,7 +70,7 @@ static MPMasterKey mpw_masterKey_v0(
|
|||||||
|
|
||||||
// Calculate the master key.
|
// Calculate the master key.
|
||||||
trc( "masterKey: scrypt( masterPassword, masterKeySalt, N=%lu, r=%u, p=%u )\n", MP_N, MP_r, MP_p );
|
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 );
|
mpw_free( masterKeySalt, masterKeySaltSize );
|
||||||
if (!masterKey) {
|
if (!masterKey) {
|
||||||
err( "Could not allocate master key: %s\n", strerror( errno ) );
|
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",
|
trc( "siteKey: hmac-sha256( masterKey.id=%s, siteSalt )\n",
|
||||||
mpw_id_buf( masterKey, MPMasterKeySize ) );
|
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 );
|
mpw_free( siteSalt, siteSaltSize );
|
||||||
if (!siteKey) {
|
if (!siteKey) {
|
||||||
err( "Could not allocate site key: %s\n", strerror( errno ) );
|
err( "Could not derive site key: %s\n", strerror( errno ) );
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
trc( " => siteKey.id: %s\n", mpw_id_buf( siteKey, MPSiteKeySize ) );
|
trc( " => siteKey.id: %s\n", mpw_id_buf( siteKey, MPSiteKeySize ) );
|
||||||
@ -124,12 +124,12 @@ static MPSiteKey mpw_siteKey_v0(
|
|||||||
return siteKey;
|
return siteKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *mpw_sitePassword_v0(
|
static const char *mpw_sitePasswordFromTemplate_v0(
|
||||||
MPSiteKey siteKey, const MPPasswordType passwordType) {
|
MPMasterKey masterKey, MPSiteKey siteKey, const MPResultType resultType, const char *resultParam) {
|
||||||
|
|
||||||
// Determine the template.
|
// Determine the template.
|
||||||
const char *_siteKey = (const char *)siteKey;
|
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 );
|
trc( "template: %u => %s\n", htons( _siteKey[0] ), template );
|
||||||
if (!template)
|
if (!template)
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -139,7 +139,7 @@ static const char *mpw_sitePassword_v0(
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Encode the password from the seed using the template.
|
// 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) {
|
for (size_t c = 0; c < strlen( template ); ++c) {
|
||||||
sitePassword[c] = mpw_characterFromClass_v0( template[c], htons( _siteKey[c + 1] ) );
|
sitePassword[c] = mpw_characterFromClass_v0( template[c], htons( _siteKey[c + 1] ) );
|
||||||
trc( " - class: %c, index: %5u (0x%02hX) => character: %c\n",
|
trc( " - class: %c, index: %5u (0x%02hX) => character: %c\n",
|
||||||
@ -150,8 +150,80 @@ static const char *mpw_sitePassword_v0(
|
|||||||
return sitePassword;
|
return sitePassword;
|
||||||
}
|
}
|
||||||
|
|
||||||
const char *mpw_encrypt_v0(
|
static const char *mpw_sitePasswordFromCrypt_v0(
|
||||||
MPMasterKey masterKey, const char *plainText) {
|
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
|
// Encrypt
|
||||||
size_t bufSize = strlen( plainText );
|
size_t bufSize = strlen( plainText );
|
||||||
@ -175,28 +247,3 @@ const char *mpw_encrypt_v0(
|
|||||||
|
|
||||||
return cipherText;
|
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;
|
|
||||||
}
|
|
||||||
|
@ -33,10 +33,12 @@ MPMasterKey mpw_masterKey_v0(
|
|||||||
MPSiteKey mpw_siteKey_v0(
|
MPSiteKey mpw_siteKey_v0(
|
||||||
MPMasterKey masterKey, const char *siteName, const MPCounterValue siteCounter,
|
MPMasterKey masterKey, const char *siteName, const MPCounterValue siteCounter,
|
||||||
const MPKeyPurpose keyPurpose, const char *keyContext);
|
const MPKeyPurpose keyPurpose, const char *keyContext);
|
||||||
const char *mpw_encrypt_v0(
|
const char *mpw_sitePasswordFromCrypt_v0(
|
||||||
MPMasterKey masterKey, const char *plainText);
|
MPMasterKey masterKey, MPSiteKey siteKey, const MPResultType resultType, const char *cipherText);
|
||||||
const char *mpw_decrypt_v0(
|
const char *mpw_sitePasswordFromDerive_v0(
|
||||||
MPMasterKey masterKey, const char *cipherText);
|
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.
|
// Algorithm version overrides.
|
||||||
static MPMasterKey mpw_masterKey_v1(
|
static MPMasterKey mpw_masterKey_v1(
|
||||||
@ -52,11 +54,11 @@ static MPSiteKey mpw_siteKey_v1(
|
|||||||
return mpw_siteKey_v0( masterKey, siteName, siteCounter, keyPurpose, keyContext );
|
return mpw_siteKey_v0( masterKey, siteName, siteCounter, keyPurpose, keyContext );
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *mpw_sitePassword_v1(
|
static const char *mpw_sitePasswordFromTemplate_v1(
|
||||||
MPSiteKey siteKey, const MPPasswordType passwordType) {
|
MPMasterKey masterKey, MPSiteKey siteKey, const MPResultType resultType, const char *resultParam) {
|
||||||
|
|
||||||
// Determine the template.
|
// 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 );
|
trc( "template: %u => %s\n", siteKey[0], template );
|
||||||
if (!template)
|
if (!template)
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -77,14 +79,20 @@ static const char *mpw_sitePassword_v1(
|
|||||||
return sitePassword;
|
return sitePassword;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *mpw_encrypt_v1(
|
static const char *mpw_sitePasswordFromCrypt_v1(
|
||||||
MPMasterKey masterKey, const char *plainText) {
|
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(
|
static const char *mpw_sitePasswordFromDerive_v1(
|
||||||
MPMasterKey masterKey, const char *cipherText) {
|
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 );
|
||||||
}
|
}
|
||||||
|
@ -30,12 +30,14 @@
|
|||||||
// Inherited functions.
|
// Inherited functions.
|
||||||
MPMasterKey mpw_masterKey_v1(
|
MPMasterKey mpw_masterKey_v1(
|
||||||
const char *fullName, const char *masterPassword);
|
const char *fullName, const char *masterPassword);
|
||||||
const char *mpw_sitePassword_v1(
|
const char *mpw_sitePasswordFromTemplate_v1(
|
||||||
MPSiteKey siteKey, const MPPasswordType passwordType);
|
MPMasterKey masterKey, MPSiteKey siteKey, const MPResultType resultType, const char *resultParam);
|
||||||
const char *mpw_encrypt_v1(
|
const char *mpw_sitePasswordFromCrypt_v1(
|
||||||
MPMasterKey masterKey, const char *plainText);
|
MPMasterKey masterKey, MPSiteKey siteKey, const MPResultType resultType, const char *cipherText);
|
||||||
const char *mpw_decrypt_v1(
|
const char *mpw_sitePasswordFromDerive_v1(
|
||||||
MPMasterKey masterKey, const char *cipherText);
|
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.
|
// Algorithm version overrides.
|
||||||
static MPMasterKey mpw_masterKey_v2(
|
static MPMasterKey mpw_masterKey_v2(
|
||||||
@ -76,7 +78,7 @@ static MPSiteKey mpw_siteKey_v2(
|
|||||||
|
|
||||||
trc( "siteKey: hmac-sha256( masterKey.id=%s, siteSalt )\n",
|
trc( "siteKey: hmac-sha256( masterKey.id=%s, siteSalt )\n",
|
||||||
mpw_id_buf( masterKey, MPMasterKeySize ) );
|
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 );
|
mpw_free( siteSalt, siteSaltSize );
|
||||||
if (!siteKey) {
|
if (!siteKey) {
|
||||||
err( "Could not allocate site key: %s\n", strerror( errno ) );
|
err( "Could not allocate site key: %s\n", strerror( errno ) );
|
||||||
@ -87,20 +89,26 @@ static MPSiteKey mpw_siteKey_v2(
|
|||||||
return siteKey;
|
return siteKey;
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *mpw_sitePassword_v2(
|
static const char *mpw_sitePasswordFromTemplate_v2(
|
||||||
MPSiteKey siteKey, const MPPasswordType passwordType) {
|
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(
|
static const char *mpw_sitePasswordFromCrypt_v2(
|
||||||
MPMasterKey masterKey, const char *plainText) {
|
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(
|
static const char *mpw_sitePasswordFromDerive_v2(
|
||||||
MPMasterKey masterKey, const char *cipherText) {
|
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 );
|
||||||
}
|
}
|
||||||
|
@ -31,12 +31,14 @@
|
|||||||
MPSiteKey mpw_siteKey_v2(
|
MPSiteKey mpw_siteKey_v2(
|
||||||
MPMasterKey masterKey, const char *siteName, const MPCounterValue siteCounter,
|
MPMasterKey masterKey, const char *siteName, const MPCounterValue siteCounter,
|
||||||
const MPKeyPurpose keyPurpose, const char *keyContext);
|
const MPKeyPurpose keyPurpose, const char *keyContext);
|
||||||
const char *mpw_sitePassword_v2(
|
const char *mpw_sitePasswordFromTemplate_v2(
|
||||||
MPSiteKey siteKey, const MPPasswordType passwordType);
|
MPMasterKey masterKey, MPSiteKey siteKey, const MPResultType resultType, const char *resultParam);
|
||||||
const char *mpw_encrypt_v2(
|
const char *mpw_sitePasswordFromCrypt_v2(
|
||||||
MPMasterKey masterKey, const char *plainText);
|
MPMasterKey masterKey, MPSiteKey siteKey, const MPResultType resultType, const char *cipherText);
|
||||||
const char *mpw_decrypt_v2(
|
const char *mpw_sitePasswordFromDerive_v2(
|
||||||
MPMasterKey masterKey, const char *cipherText);
|
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.
|
// Algorithm version overrides.
|
||||||
static MPMasterKey mpw_masterKey_v3(
|
static MPMasterKey mpw_masterKey_v3(
|
||||||
@ -61,7 +63,7 @@ static MPMasterKey mpw_masterKey_v3(
|
|||||||
|
|
||||||
// Calculate the master key.
|
// Calculate the master key.
|
||||||
trc( "masterKey: scrypt( masterPassword, masterKeySalt, N=%lu, r=%u, p=%u )\n", MP_N, MP_r, MP_p );
|
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 );
|
mpw_free( masterKeySalt, masterKeySaltSize );
|
||||||
if (!masterKey) {
|
if (!masterKey) {
|
||||||
err( "Could not allocate master key: %s\n", strerror( errno ) );
|
err( "Could not allocate master key: %s\n", strerror( errno ) );
|
||||||
@ -73,26 +75,32 @@ static MPMasterKey mpw_masterKey_v3(
|
|||||||
}
|
}
|
||||||
|
|
||||||
static MPSiteKey mpw_siteKey_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) {
|
const MPKeyPurpose keyPurpose, const char *keyContext) {
|
||||||
|
|
||||||
return mpw_siteKey_v2( masterKey, siteName, siteCounter, keyPurpose, keyContext );
|
return mpw_siteKey_v2( masterKey, siteName, siteCounter, keyPurpose, keyContext );
|
||||||
}
|
}
|
||||||
|
|
||||||
static const char *mpw_sitePassword_v3(
|
static const char *mpw_sitePasswordFromTemplate_v3(
|
||||||
MPSiteKey siteKey, const MPPasswordType passwordType) {
|
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(
|
static const char *mpw_sitePasswordFromCrypt_v3(
|
||||||
MPMasterKey masterKey, const char *plainText) {
|
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(
|
static const char *mpw_sitePasswordFromDerive_v3(
|
||||||
MPMasterKey masterKey, const char *cipherText) {
|
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 );
|
||||||
}
|
}
|
||||||
|
@ -39,7 +39,7 @@ MPMarshalledUser *mpw_marshall_user(
|
|||||||
.redacted = true,
|
.redacted = true,
|
||||||
|
|
||||||
.avatar = 0,
|
.avatar = 0,
|
||||||
.defaultType = MPPasswordTypeDefault,
|
.defaultType = MPResultTypeDefault,
|
||||||
.lastUsed = 0,
|
.lastUsed = 0,
|
||||||
|
|
||||||
.sites_count = 0,
|
.sites_count = 0,
|
||||||
@ -49,7 +49,7 @@ MPMarshalledUser *mpw_marshall_user(
|
|||||||
};
|
};
|
||||||
|
|
||||||
MPMarshalledSite *mpw_marshall_site(
|
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) {
|
const MPCounterValue siteCounter, const MPAlgorithmVersion algorithmVersion) {
|
||||||
|
|
||||||
if (!siteName || !mpw_realloc( &user->sites, NULL, sizeof( MPMarshalledSite ) * ++user->sites_count ))
|
if (!siteName || !mpw_realloc( &user->sites, NULL, sizeof( MPMarshalledSite ) * ++user->sites_count ))
|
||||||
@ -59,7 +59,7 @@ MPMarshalledSite *mpw_marshall_site(
|
|||||||
*site = (MPMarshalledSite){
|
*site = (MPMarshalledSite){
|
||||||
.name = strdup( siteName ),
|
.name = strdup( siteName ),
|
||||||
.content = NULL,
|
.content = NULL,
|
||||||
.type = passwordType,
|
.type = resultType,
|
||||||
.counter = siteCounter,
|
.counter = siteCounter,
|
||||||
.algorithm = algorithmVersion,
|
.algorithm = algorithmVersion,
|
||||||
|
|
||||||
@ -171,13 +171,9 @@ static bool mpw_marshall_write_flat(
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (site->type & MPPasswordTypeClassGenerated) {
|
if (site->type & MPResultTypeClassTemplate)
|
||||||
MPSiteKey siteKey = mpw_siteKey( masterKey, site->name, site->counter, MPKeyPurposeAuthentication, NULL, site->algorithm );
|
content = mpw_siteResult( masterKey, site->name, site->counter,
|
||||||
content = mpw_sitePassword( siteKey, site->type, site->algorithm );
|
MPKeyPurposeAuthentication, NULL, site->type, site->content, site->algorithm );
|
||||||
mpw_free( siteKey, MPSiteKeySize );
|
|
||||||
}
|
|
||||||
else if (site->type & MPSiteFeatureExportContent && site->content && strlen( site->content ))
|
|
||||||
content = mpw_decrypt( masterKey, site->content, site->algorithm );
|
|
||||||
}
|
}
|
||||||
else if (site->type & MPSiteFeatureExportContent && site->content && strlen( site->content ))
|
else if (site->type & MPSiteFeatureExportContent && site->content && strlen( site->content ))
|
||||||
// Redacted
|
// Redacted
|
||||||
@ -255,13 +251,9 @@ static bool mpw_marshall_write_json(
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (site->type & MPPasswordTypeClassGenerated) {
|
if (site->type & MPResultTypeClassTemplate)
|
||||||
MPSiteKey siteKey = mpw_siteKey( masterKey, site->name, site->counter, MPKeyPurposeAuthentication, NULL, site->algorithm );
|
content = mpw_siteResult( masterKey, site->name, site->counter,
|
||||||
content = mpw_sitePassword( siteKey, site->type, site->algorithm );
|
MPKeyPurposeAuthentication, NULL, site->type, site->content, site->algorithm );
|
||||||
mpw_free( siteKey, MPSiteKeySize );
|
|
||||||
}
|
|
||||||
else if (site->type & MPSiteFeatureExportContent && site->content && strlen( site->content ))
|
|
||||||
content = mpw_decrypt( masterKey, site->content, site->algorithm );
|
|
||||||
}
|
}
|
||||||
else if (site->type & MPSiteFeatureExportContent && site->content && strlen( site->content ))
|
else if (site->type & MPSiteFeatureExportContent && site->content && strlen( site->content ))
|
||||||
// Redacted
|
// Redacted
|
||||||
@ -294,10 +286,8 @@ static bool mpw_marshall_write_json(
|
|||||||
|
|
||||||
if (!user->redacted) {
|
if (!user->redacted) {
|
||||||
// Clear Text
|
// Clear Text
|
||||||
MPSiteKey siteKey = mpw_siteKey( masterKey, site->name,
|
const char *answer = mpw_siteResult( masterKey, site->name, MPCounterValueInitial,
|
||||||
MPCounterValueInitial, MPKeyPurposeRecovery, question->keyword, site->algorithm );
|
MPKeyPurposeRecovery, question->keyword, MPResultTypeTemplatePhrase, NULL, site->algorithm );
|
||||||
const char *answer = mpw_sitePassword( siteKey, MPPasswordTypeGeneratedPhrase, site->algorithm );
|
|
||||||
mpw_free( siteKey, MPSiteKeySize );
|
|
||||||
if (answer)
|
if (answer)
|
||||||
json_object_object_add( json_site_question, "answer", json_object_new_string( answer ) );
|
json_object_object_add( json_site_question, "answer", json_object_new_string( answer ) );
|
||||||
}
|
}
|
||||||
@ -327,11 +317,11 @@ bool mpw_marshall_write(
|
|||||||
return mpw_marshall_write_flat( out, user, error );
|
return mpw_marshall_write_flat( out, user, error );
|
||||||
case MPMarshallFormatJSON:
|
case MPMarshallFormatJSON:
|
||||||
return mpw_marshall_write_json( out, user, error );
|
return mpw_marshall_write_json( out, user, error );
|
||||||
}
|
default:
|
||||||
|
|
||||||
*error = (MPMarshallError){ MPMarshallErrorFormat, mpw_str( "Unsupported output format: %u", outFormat ) };
|
*error = (MPMarshallError){ MPMarshallErrorFormat, mpw_str( "Unsupported output format: %u", outFormat ) };
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static MPMarshalledUser *mpw_marshall_read_flat(
|
static MPMarshalledUser *mpw_marshall_read_flat(
|
||||||
char *in, const char *masterPassword, MPMarshallError *error) {
|
char *in, const char *masterPassword, MPMarshallError *error) {
|
||||||
@ -344,7 +334,7 @@ static MPMarshalledUser *mpw_marshall_read_flat(
|
|||||||
unsigned int format = 0, avatar = 0;
|
unsigned int format = 0, avatar = 0;
|
||||||
char *fullName = NULL, *keyID = NULL;
|
char *fullName = NULL, *keyID = NULL;
|
||||||
MPAlgorithmVersion algorithm = MPAlgorithmVersionCurrent, masterKeyAlgorithm = (MPAlgorithmVersion)-1;
|
MPAlgorithmVersion algorithm = MPAlgorithmVersionCurrent, masterKeyAlgorithm = (MPAlgorithmVersion)-1;
|
||||||
MPPasswordType defaultType = MPPasswordTypeDefault;
|
MPResultType defaultType = MPResultTypeDefault;
|
||||||
bool headerStarted = false, headerEnded = false, importRedacted = false;
|
bool headerStarted = false, headerEnded = false, importRedacted = false;
|
||||||
for (char *endOfLine, *positionInLine = in; (endOfLine = strstr( positionInLine, "\n" )); positionInLine = endOfLine + 1) {
|
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) {
|
if (strcmp( headerName, "Default Type" ) == 0) {
|
||||||
int value = atoi( headerValue );
|
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 ) };
|
*error = (MPMarshallError){ MPMarshallErrorIllegal, mpw_str( "Invalid user default type: %s", headerValue ) };
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
defaultType = (MPPasswordType)value;
|
defaultType = (MPResultType)value;
|
||||||
}
|
}
|
||||||
if (strcmp( headerName, "Passwords" ) == 0)
|
if (strcmp( headerName, "Passwords" ) == 0)
|
||||||
importRedacted = strcmp( headerValue, "VISIBLE" ) != 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) {
|
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 )) {
|
if (!mpw_nameForType( siteType )) {
|
||||||
*error = (MPMarshallError){ MPMarshallErrorIllegal, mpw_str( "Invalid site type: %s: %s", siteName, str_type ) };
|
*error = (MPMarshallError){ MPMarshallErrorIllegal, mpw_str( "Invalid site type: %s: %s", siteName, str_type ) };
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -518,7 +508,8 @@ static MPMarshalledUser *mpw_marshall_read_flat(
|
|||||||
return NULL;
|
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
|
else
|
||||||
// Redacted
|
// Redacted
|
||||||
@ -587,7 +578,7 @@ static MPMarshalledUser *mpw_marshall_read_json(
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
MPAlgorithmVersion algorithm = (MPAlgorithmVersion)value;
|
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 )) {
|
if (!mpw_nameForType( defaultType )) {
|
||||||
*error = (MPMarshallError){ MPMarshallErrorIllegal, mpw_str( "Invalid user default type: %u", defaultType ) };
|
*error = (MPMarshallError){ MPMarshallErrorIllegal, mpw_str( "Invalid user default type: %u", defaultType ) };
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -629,7 +620,7 @@ static MPMarshalledUser *mpw_marshall_read_json(
|
|||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
MPAlgorithmVersion siteAlgorithm = (MPAlgorithmVersion)value;
|
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 )) {
|
if (!mpw_nameForType( siteType )) {
|
||||||
*error = (MPMarshallError){ MPMarshallErrorIllegal, mpw_str( "Invalid site type: %s: %u", siteName, siteType ) };
|
*error = (MPMarshallError){ MPMarshallErrorIllegal, mpw_str( "Invalid site type: %s: %u", siteName, siteType ) };
|
||||||
return NULL;
|
return NULL;
|
||||||
@ -673,7 +664,8 @@ static MPMarshalledUser *mpw_marshall_read_json(
|
|||||||
return NULL;
|
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
|
else
|
||||||
// Redacted
|
// Redacted
|
||||||
@ -699,11 +691,11 @@ MPMarshalledUser *mpw_marshall_read(
|
|||||||
return mpw_marshall_read_flat( in, masterPassword, error );
|
return mpw_marshall_read_flat( in, masterPassword, error );
|
||||||
case MPMarshallFormatJSON:
|
case MPMarshallFormatJSON:
|
||||||
return mpw_marshall_read_json( in, masterPassword, error );
|
return mpw_marshall_read_json( in, masterPassword, error );
|
||||||
}
|
default:
|
||||||
|
|
||||||
*error = (MPMarshallError){ MPMarshallErrorFormat, mpw_str( "Unsupported input format: %u", inFormat ) };
|
*error = (MPMarshallError){ MPMarshallErrorFormat, mpw_str( "Unsupported input format: %u", inFormat ) };
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
const MPMarshallFormat mpw_formatWithName(
|
const MPMarshallFormat mpw_formatWithName(
|
||||||
const char *formatName) {
|
const char *formatName) {
|
||||||
|
@ -62,7 +62,7 @@ typedef struct MPMarshalledQuestion {
|
|||||||
typedef struct MPMarshalledSite {
|
typedef struct MPMarshalledSite {
|
||||||
const char *name;
|
const char *name;
|
||||||
const char *content;
|
const char *content;
|
||||||
MPPasswordType type;
|
MPResultType type;
|
||||||
MPCounterValue counter;
|
MPCounterValue counter;
|
||||||
MPAlgorithmVersion algorithm;
|
MPAlgorithmVersion algorithm;
|
||||||
|
|
||||||
@ -84,7 +84,7 @@ typedef struct MPMarshalledUser {
|
|||||||
bool redacted;
|
bool redacted;
|
||||||
|
|
||||||
unsigned int avatar;
|
unsigned int avatar;
|
||||||
MPPasswordType defaultType;
|
MPResultType defaultType;
|
||||||
time_t lastUsed;
|
time_t lastUsed;
|
||||||
|
|
||||||
size_t sites_count;
|
size_t sites_count;
|
||||||
@ -104,7 +104,7 @@ MPMarshalledUser *mpw_marshall_user(
|
|||||||
const char *fullName, const char *masterPassword, const MPAlgorithmVersion algorithmVersion);
|
const char *fullName, const char *masterPassword, const MPAlgorithmVersion algorithmVersion);
|
||||||
MPMarshalledSite *mpw_marshall_site(
|
MPMarshalledSite *mpw_marshall_site(
|
||||||
MPMarshalledUser *user,
|
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(
|
MPMarshalledQuestion *mpw_marshal_question(
|
||||||
MPMarshalledSite *site, const char *keyword);
|
MPMarshalledSite *site, const char *keyword);
|
||||||
bool mpw_marshal_free(
|
bool mpw_marshal_free(
|
||||||
|
@ -29,28 +29,30 @@
|
|||||||
#include "mpw-types.h"
|
#include "mpw-types.h"
|
||||||
#include "mpw-util.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.
|
// Find what password type is represented by the type letter.
|
||||||
if (strlen( typeName ) == 1) {
|
if (strlen( typeName ) == 1) {
|
||||||
if ('x' == typeName[0])
|
if ('x' == typeName[0])
|
||||||
return MPPasswordTypeGeneratedMaximum;
|
return MPResultTypeTemplateMaximum;
|
||||||
if ('l' == typeName[0])
|
if ('l' == typeName[0])
|
||||||
return MPPasswordTypeGeneratedLong;
|
return MPResultTypeTemplateLong;
|
||||||
if ('m' == typeName[0])
|
if ('m' == typeName[0])
|
||||||
return MPPasswordTypeGeneratedMedium;
|
return MPResultTypeTemplateMedium;
|
||||||
if ('b' == typeName[0])
|
if ('b' == typeName[0])
|
||||||
return MPPasswordTypeGeneratedBasic;
|
return MPResultTypeTemplateBasic;
|
||||||
if ('s' == typeName[0])
|
if ('s' == typeName[0])
|
||||||
return MPPasswordTypeGeneratedShort;
|
return MPResultTypeTemplateShort;
|
||||||
if ('i' == typeName[0])
|
if ('i' == typeName[0])
|
||||||
return MPPasswordTypeGeneratedPIN;
|
return MPResultTypeTemplatePIN;
|
||||||
if ('n' == typeName[0])
|
if ('n' == typeName[0])
|
||||||
return MPPasswordTypeGeneratedName;
|
return MPResultTypeTemplateName;
|
||||||
if ('P' == typeName[0])
|
if ('P' == typeName[0])
|
||||||
return MPPasswordTypeStoredPersonal;
|
return MPResultTypeStatePersonal;
|
||||||
if ('D' == typeName[0])
|
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.
|
// 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';
|
stdTypeName[stdTypeNameSize] = '\0';
|
||||||
|
|
||||||
// Find what password type is represented by the type name.
|
// Find what password type is represented by the type name.
|
||||||
if (strncmp( mpw_nameForType( MPPasswordTypeGeneratedPhrase ), stdTypeName, strlen( stdTypeName ) ) == 0)
|
if (strncmp( mpw_nameForType( MPResultTypeTemplateMaximum ), stdTypeName, strlen( stdTypeName ) ) == 0)
|
||||||
return MPPasswordTypeGeneratedPhrase;
|
return MPResultTypeTemplateMaximum;
|
||||||
if (strncmp( mpw_nameForType( MPPasswordTypeGeneratedMaximum ), stdTypeName, strlen( stdTypeName ) ) == 0)
|
if (strncmp( mpw_nameForType( MPResultTypeTemplateLong ), stdTypeName, strlen( stdTypeName ) ) == 0)
|
||||||
return MPPasswordTypeGeneratedMaximum;
|
return MPResultTypeTemplateLong;
|
||||||
if (strncmp( mpw_nameForType( MPPasswordTypeGeneratedLong ), stdTypeName, strlen( stdTypeName ) ) == 0)
|
if (strncmp( mpw_nameForType( MPResultTypeTemplateMedium ), stdTypeName, strlen( stdTypeName ) ) == 0)
|
||||||
return MPPasswordTypeGeneratedLong;
|
return MPResultTypeTemplateMedium;
|
||||||
if (strncmp( mpw_nameForType( MPPasswordTypeGeneratedMedium ), stdTypeName, strlen( stdTypeName ) ) == 0)
|
if (strncmp( mpw_nameForType( MPResultTypeTemplateBasic ), stdTypeName, strlen( stdTypeName ) ) == 0)
|
||||||
return MPPasswordTypeGeneratedMedium;
|
return MPResultTypeTemplateBasic;
|
||||||
if (strncmp( mpw_nameForType( MPPasswordTypeGeneratedBasic ), stdTypeName, strlen( stdTypeName ) ) == 0)
|
if (strncmp( mpw_nameForType( MPResultTypeTemplateShort ), stdTypeName, strlen( stdTypeName ) ) == 0)
|
||||||
return MPPasswordTypeGeneratedBasic;
|
return MPResultTypeTemplateShort;
|
||||||
if (strncmp( mpw_nameForType( MPPasswordTypeGeneratedShort ), stdTypeName, strlen( stdTypeName ) ) == 0)
|
if (strncmp( mpw_nameForType( MPResultTypeTemplatePIN ), stdTypeName, strlen( stdTypeName ) ) == 0)
|
||||||
return MPPasswordTypeGeneratedShort;
|
return MPResultTypeTemplatePIN;
|
||||||
if (strncmp( mpw_nameForType( MPPasswordTypeGeneratedPIN ), stdTypeName, strlen( stdTypeName ) ) == 0)
|
if (strncmp( mpw_nameForType( MPResultTypeTemplateName ), stdTypeName, strlen( stdTypeName ) ) == 0)
|
||||||
return MPPasswordTypeGeneratedPIN;
|
return MPResultTypeTemplateName;
|
||||||
if (strncmp( mpw_nameForType( MPPasswordTypeGeneratedName ), stdTypeName, strlen( stdTypeName ) ) == 0)
|
if (strncmp( mpw_nameForType( MPResultTypeTemplatePhrase ), stdTypeName, strlen( stdTypeName ) ) == 0)
|
||||||
return MPPasswordTypeGeneratedName;
|
return MPResultTypeTemplatePhrase;
|
||||||
if (strncmp( mpw_nameForType( MPPasswordTypeGeneratedPhrase ), stdTypeName, strlen( stdTypeName ) ) == 0)
|
if (strncmp( mpw_nameForType( MPResultTypeStatePersonal ), stdTypeName, strlen( stdTypeName ) ) == 0)
|
||||||
return MPPasswordTypeGeneratedPhrase;
|
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 );
|
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) {
|
switch (resultType) {
|
||||||
case MPPasswordTypeGeneratedMaximum:
|
case MPResultTypeTemplateMaximum:
|
||||||
return "maximum";
|
return "maximum";
|
||||||
case MPPasswordTypeGeneratedLong:
|
case MPResultTypeTemplateLong:
|
||||||
return "long";
|
return "long";
|
||||||
case MPPasswordTypeGeneratedMedium:
|
case MPResultTypeTemplateMedium:
|
||||||
return "medium";
|
return "medium";
|
||||||
case MPPasswordTypeGeneratedBasic:
|
case MPResultTypeTemplateBasic:
|
||||||
return "basic";
|
return "basic";
|
||||||
case MPPasswordTypeGeneratedShort:
|
case MPResultTypeTemplateShort:
|
||||||
return "short";
|
return "short";
|
||||||
case MPPasswordTypeGeneratedPIN:
|
case MPResultTypeTemplatePIN:
|
||||||
return "pin";
|
return "pin";
|
||||||
case MPPasswordTypeGeneratedName:
|
case MPResultTypeTemplateName:
|
||||||
return "name";
|
return "name";
|
||||||
case MPPasswordTypeGeneratedPhrase:
|
case MPResultTypeTemplatePhrase:
|
||||||
return "phrase";
|
return "phrase";
|
||||||
case MPPasswordTypeStoredPersonal:
|
case MPResultTypeStatePersonal:
|
||||||
return "personal";
|
return "personal";
|
||||||
case MPPasswordTypeStoredDevice:
|
case MPResultTypeStateDevice:
|
||||||
return "device";
|
return "device";
|
||||||
|
case MPResultTypeDeriveKey:
|
||||||
|
return "key";
|
||||||
default: {
|
default: {
|
||||||
dbg( "Unknown password type: %d\n", passwordType );
|
dbg( "Unknown password type: %d\n", resultType );
|
||||||
return NULL;
|
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 );
|
dbg( "Not a generated type: %d\n", type );
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (type) {
|
switch (type) {
|
||||||
case MPPasswordTypeGeneratedMaximum:
|
case MPResultTypeTemplateMaximum:
|
||||||
return mpw_alloc_array( count, const char *,
|
return mpw_alloc_array( count, const char *,
|
||||||
"anoxxxxxxxxxxxxxxxxx", "axxxxxxxxxxxxxxxxxno" );
|
"anoxxxxxxxxxxxxxxxxx", "axxxxxxxxxxxxxxxxxno" );
|
||||||
case MPPasswordTypeGeneratedLong:
|
case MPResultTypeTemplateLong:
|
||||||
return mpw_alloc_array( count, const char *,
|
return mpw_alloc_array( count, const char *,
|
||||||
"CvcvnoCvcvCvcv", "CvcvCvcvnoCvcv", "CvcvCvcvCvcvno",
|
"CvcvnoCvcvCvcv", "CvcvCvcvnoCvcv", "CvcvCvcvCvcvno",
|
||||||
"CvccnoCvcvCvcv", "CvccCvcvnoCvcv", "CvccCvcvCvcvno",
|
"CvccnoCvcvCvcv", "CvccCvcvnoCvcv", "CvccCvcvCvcvno",
|
||||||
@ -137,22 +145,22 @@ const char **mpw_templatesForType(MPPasswordType type, size_t *count) {
|
|||||||
"CvccnoCvccCvcv", "CvccCvccnoCvcv", "CvccCvccCvcvno",
|
"CvccnoCvccCvcv", "CvccCvccnoCvcv", "CvccCvccCvcvno",
|
||||||
"CvcvnoCvccCvcc", "CvcvCvccnoCvcc", "CvcvCvccCvccno",
|
"CvcvnoCvccCvcc", "CvcvCvccnoCvcc", "CvcvCvccCvccno",
|
||||||
"CvccnoCvcvCvcc", "CvccCvcvnoCvcc", "CvccCvcvCvccno" );
|
"CvccnoCvcvCvcc", "CvccCvcvnoCvcc", "CvccCvcvCvccno" );
|
||||||
case MPPasswordTypeGeneratedMedium:
|
case MPResultTypeTemplateMedium:
|
||||||
return mpw_alloc_array( count, const char *,
|
return mpw_alloc_array( count, const char *,
|
||||||
"CvcnoCvc", "CvcCvcno" );
|
"CvcnoCvc", "CvcCvcno" );
|
||||||
case MPPasswordTypeGeneratedBasic:
|
case MPResultTypeTemplateBasic:
|
||||||
return mpw_alloc_array( count, const char *,
|
return mpw_alloc_array( count, const char *,
|
||||||
"aaanaaan", "aannaaan", "aaannaaa" );
|
"aaanaaan", "aannaaan", "aaannaaa" );
|
||||||
case MPPasswordTypeGeneratedShort:
|
case MPResultTypeTemplateShort:
|
||||||
return mpw_alloc_array( count, const char *,
|
return mpw_alloc_array( count, const char *,
|
||||||
"Cvcn" );
|
"Cvcn" );
|
||||||
case MPPasswordTypeGeneratedPIN:
|
case MPResultTypeTemplatePIN:
|
||||||
return mpw_alloc_array( count, const char *,
|
return mpw_alloc_array( count, const char *,
|
||||||
"nnnn" );
|
"nnnn" );
|
||||||
case MPPasswordTypeGeneratedName:
|
case MPResultTypeTemplateName:
|
||||||
return mpw_alloc_array( count, const char *,
|
return mpw_alloc_array( count, const char *,
|
||||||
"cvccvcvcv" );
|
"cvccvcvcv" );
|
||||||
case MPPasswordTypeGeneratedPhrase:
|
case MPResultTypeTemplatePhrase:
|
||||||
return mpw_alloc_array( count, const char *,
|
return mpw_alloc_array( count, const char *,
|
||||||
"cvcc cvc cvccvcv cvc", "cvc cvccvcvcv cvcv", "cv cvccv cvc cvcvccv" );
|
"cvcc cvc cvccvcv cvc", "cvc cvccvcvcv cvcv", "cv cvccv cvc cvcvccv" );
|
||||||
default: {
|
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;
|
size_t count = 0;
|
||||||
const char **templates = mpw_templatesForType( type, &count );
|
const char **templates = mpw_templatesForType( type, &count );
|
||||||
|
@ -23,11 +23,11 @@
|
|||||||
#include <stdint.h>
|
#include <stdint.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
|
||||||
#ifdef NS_ENUM
|
//#ifdef NS_ENUM
|
||||||
#define enum(_type, _name) NS_ENUM(_type, _name)
|
//#define enum(_type, _name) NS_ENUM(_type, _name)
|
||||||
#else
|
//#else
|
||||||
#define enum(_type, _name) _type _name; enum
|
#define enum(_type, _name) _type _name; enum
|
||||||
#endif
|
//#endif
|
||||||
|
|
||||||
//// Types.
|
//// Types.
|
||||||
|
|
||||||
@ -47,11 +47,13 @@ typedef enum( uint8_t, MPKeyPurpose ) {
|
|||||||
};
|
};
|
||||||
|
|
||||||
// bit 4 - 9
|
// bit 4 - 9
|
||||||
typedef enum( uint16_t, MPPasswordTypeClass ) {
|
typedef enum( uint16_t, MPResultTypeClass ) {
|
||||||
/** Generate the password. */
|
/** Use the site key to generate a password from a template. */
|
||||||
MPPasswordTypeClassGenerated = 1 << 4,
|
MPResultTypeClassTemplate = 1 << 4,
|
||||||
/** Store the password. */
|
/** Use the site key to encrypt and decrypt a stateful entity. */
|
||||||
MPPasswordTypeClassStored = 1 << 5,
|
MPResultTypeClassState = 1 << 5,
|
||||||
|
/** Use the site key to derive a site-specific object. */
|
||||||
|
MPResultTypeClassDerive = 1 << 6,
|
||||||
};
|
};
|
||||||
|
|
||||||
// bit 10 - 15
|
// bit 10 - 15
|
||||||
@ -60,33 +62,38 @@ typedef enum( uint16_t, MPSiteFeature ) {
|
|||||||
MPSiteFeatureExportContent = 1 << 10,
|
MPSiteFeatureExportContent = 1 << 10,
|
||||||
/** Never export content. */
|
/** Never export content. */
|
||||||
MPSiteFeatureDevicePrivate = 1 << 11,
|
MPSiteFeatureDevicePrivate = 1 << 11,
|
||||||
|
/** Don't use this as the primary authentication result type. */
|
||||||
|
MPSiteFeatureAlternative = 1 << 12,
|
||||||
};
|
};
|
||||||
|
|
||||||
// bit 0-3 | MPPasswordTypeClass | MPSiteFeature
|
// bit 0-3 | MPResultTypeClass | MPSiteFeature
|
||||||
typedef enum( uint32_t, MPPasswordType ) {
|
typedef enum( uint32_t, MPResultType ) {
|
||||||
/** pg^VMAUBk5x3p%HP%i4= */
|
/** pg^VMAUBk5x3p%HP%i4= */
|
||||||
MPPasswordTypeGeneratedMaximum = 0x0 | MPPasswordTypeClassGenerated | 0x0,
|
MPResultTypeTemplateMaximum = 0x0 | MPResultTypeClassTemplate | 0x0,
|
||||||
/** BiroYena8:Kixa */
|
/** BiroYena8:Kixa */
|
||||||
MPPasswordTypeGeneratedLong = 0x1 | MPPasswordTypeClassGenerated | 0x0,
|
MPResultTypeTemplateLong = 0x1 | MPResultTypeClassTemplate | 0x0,
|
||||||
/** BirSuj0- */
|
/** BirSuj0- */
|
||||||
MPPasswordTypeGeneratedMedium = 0x2 | MPPasswordTypeClassGenerated | 0x0,
|
MPResultTypeTemplateMedium = 0x2 | MPResultTypeClassTemplate | 0x0,
|
||||||
/** pO98MoD0 */
|
/** pO98MoD0 */
|
||||||
MPPasswordTypeGeneratedBasic = 0x4 | MPPasswordTypeClassGenerated | 0x0,
|
MPResultTypeTemplateBasic = 0x4 | MPResultTypeClassTemplate | 0x0,
|
||||||
/** Bir8 */
|
/** Bir8 */
|
||||||
MPPasswordTypeGeneratedShort = 0x3 | MPPasswordTypeClassGenerated | 0x0,
|
MPResultTypeTemplateShort = 0x3 | MPResultTypeClassTemplate | 0x0,
|
||||||
/** 2798 */
|
/** 2798 */
|
||||||
MPPasswordTypeGeneratedPIN = 0x5 | MPPasswordTypeClassGenerated | 0x0,
|
MPResultTypeTemplatePIN = 0x5 | MPResultTypeClassTemplate | 0x0,
|
||||||
/** birsujano */
|
/** birsujano */
|
||||||
MPPasswordTypeGeneratedName = 0xE | MPPasswordTypeClassGenerated | 0x0,
|
MPResultTypeTemplateName = 0xE | MPResultTypeClassTemplate | 0x0,
|
||||||
/** bir yennoquce fefi */
|
/** bir yennoquce fefi */
|
||||||
MPPasswordTypeGeneratedPhrase = 0xF | MPPasswordTypeClassGenerated | 0x0,
|
MPResultTypeTemplatePhrase = 0xF | MPResultTypeClassTemplate | 0x0,
|
||||||
|
|
||||||
/** Custom saved password. */
|
/** Custom saved password. */
|
||||||
MPPasswordTypeStoredPersonal = 0x0 | MPPasswordTypeClassStored | MPSiteFeatureExportContent,
|
MPResultTypeStatePersonal = 0x0 | MPResultTypeClassState | MPSiteFeatureExportContent,
|
||||||
/** Custom saved password that should not be exported from the device. */
|
/** 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 ) {
|
typedef enum ( uint32_t, MPCounterValue ) {
|
||||||
@ -118,11 +125,11 @@ const char *mpw_scopeForPurpose(MPKeyPurpose purpose);
|
|||||||
/**
|
/**
|
||||||
* @return The password type represented by the given name.
|
* @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.
|
* @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.
|
* @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.
|
* 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.
|
* 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
|
* @return An internal string that contains the password encoding template of the given type
|
||||||
* for a seed that starts with the given byte.
|
* 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.
|
* @return An internal string that contains all the characters that occur in the given character class.
|
||||||
|
@ -18,6 +18,7 @@
|
|||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
#include <errno.h>
|
||||||
|
|
||||||
#if MPW_COLOR
|
#if MPW_COLOR
|
||||||
#include <unistd.h>
|
#include <unistd.h>
|
||||||
@ -32,6 +33,7 @@
|
|||||||
#include "sodium.h"
|
#include "sodium.h"
|
||||||
#ifdef SODIUM_LIBRARY_MINIMAL
|
#ifdef SODIUM_LIBRARY_MINIMAL
|
||||||
#include "crypto_stream_aes128ctr.h"
|
#include "crypto_stream_aes128ctr.h"
|
||||||
|
#include "crypto_kdf_blake2b.h"
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@ -122,7 +124,7 @@ bool mpw_free_string(const char *string) {
|
|||||||
return string && mpw_free( string, strlen( 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) {
|
uint64_t N, uint32_t r, uint32_t p) {
|
||||||
|
|
||||||
if (!secret || !salt)
|
if (!secret || !salt)
|
||||||
@ -149,7 +151,49 @@ uint8_t const *mpw_scrypt(const size_t keySize, const char *secret, const uint8_
|
|||||||
return key;
|
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)
|
if (!key || !keySize || !message || !messageSize)
|
||||||
return NULL;
|
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 ) );
|
strlen( fullName ) );
|
||||||
if (!identiconSeed)
|
if (!identiconSeed)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
@ -141,12 +141,17 @@ bool mpw_free_string(
|
|||||||
|
|
||||||
/** Derive a key from the given secret and salt using the scrypt KDF.
|
/** Derive a key from the given secret and salt using the scrypt KDF.
|
||||||
* @return A new keySize allocated buffer containing the key. */
|
* @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,
|
const size_t keySize, const char *secret, const uint8_t *salt, const size_t saltSize,
|
||||||
uint64_t N, uint32_t r, uint32_t p);
|
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.
|
/** Calculate the MAC for the given message with the given key using SHA256-HMAC.
|
||||||
* @return A new 32-byte allocated buffer containing the MAC. */
|
* @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);
|
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.
|
/** Encrypt a plainBuf with the given key using AES-128-CBC.
|
||||||
* @return A new bufSize allocated buffer containing the cipherBuf. */
|
* @return A new bufSize allocated buffer containing the cipherBuf. */
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
<keyID>98EEF4D1DF46D849574A82A03C3177056B15DFFCA29BB3899DE4628453675302</keyID>
|
<keyID>98EEF4D1DF46D849574A82A03C3177056B15DFFCA29BB3899DE4628453675302</keyID>
|
||||||
<siteName>masterpasswordapp.com</siteName>
|
<siteName>masterpasswordapp.com</siteName>
|
||||||
<siteCounter>1</siteCounter>
|
<siteCounter>1</siteCounter>
|
||||||
<passwordType>GeneratedLong</passwordType>
|
<resultType>GeneratedLong</resultType>
|
||||||
<keyPurpose>Authentication</keyPurpose>
|
<keyPurpose>Authentication</keyPurpose>
|
||||||
<result><!-- abstract --></result>
|
<result><!-- abstract --></result>
|
||||||
</case>
|
</case>
|
||||||
@ -33,12 +33,12 @@
|
|||||||
</case>
|
</case>
|
||||||
<case id="v3_loginName" parent="v3">
|
<case id="v3_loginName" parent="v3">
|
||||||
<keyPurpose>Identification</keyPurpose>
|
<keyPurpose>Identification</keyPurpose>
|
||||||
<passwordType>GeneratedName</passwordType>
|
<resultType>GeneratedName</resultType>
|
||||||
<result>wohzaqage</result>
|
<result>wohzaqage</result>
|
||||||
</case>
|
</case>
|
||||||
<case id="v3_securityAnswer" parent="v3">
|
<case id="v3_securityAnswer" parent="v3">
|
||||||
<keyPurpose>Recovery</keyPurpose>
|
<keyPurpose>Recovery</keyPurpose>
|
||||||
<passwordType>GeneratedPhrase</passwordType>
|
<resultType>GeneratedPhrase</resultType>
|
||||||
<result>xin diyjiqoja hubu</result>
|
<result>xin diyjiqoja hubu</result>
|
||||||
</case>
|
</case>
|
||||||
<case id="v3_securityAnswer_context" parent="v3_securityAnswer">
|
<case id="v3_securityAnswer_context" parent="v3_securityAnswer">
|
||||||
@ -46,31 +46,31 @@
|
|||||||
<result>xogx tem cegyiva jab</result>
|
<result>xogx tem cegyiva jab</result>
|
||||||
</case>
|
</case>
|
||||||
<case id="v3_type_maximum" parent="v3">
|
<case id="v3_type_maximum" parent="v3">
|
||||||
<passwordType>GeneratedMaximum</passwordType>
|
<resultType>GeneratedMaximum</resultType>
|
||||||
<result>W6@692^B1#&@gVdSdLZ@</result>
|
<result>W6@692^B1#&@gVdSdLZ@</result>
|
||||||
</case>
|
</case>
|
||||||
<case id="v3_type_medium" parent="v3">
|
<case id="v3_type_medium" parent="v3">
|
||||||
<passwordType>GeneratedMedium</passwordType>
|
<resultType>GeneratedMedium</resultType>
|
||||||
<result>Jej2$Quv</result>
|
<result>Jej2$Quv</result>
|
||||||
</case>
|
</case>
|
||||||
<case id="v3_type_basic" parent="v3">
|
<case id="v3_type_basic" parent="v3">
|
||||||
<passwordType>GeneratedBasic</passwordType>
|
<resultType>GeneratedBasic</resultType>
|
||||||
<result>WAo2xIg6</result>
|
<result>WAo2xIg6</result>
|
||||||
</case>
|
</case>
|
||||||
<case id="v3_type_short" parent="v3">
|
<case id="v3_type_short" parent="v3">
|
||||||
<passwordType>GeneratedShort</passwordType>
|
<resultType>GeneratedShort</resultType>
|
||||||
<result>Jej2</result>
|
<result>Jej2</result>
|
||||||
</case>
|
</case>
|
||||||
<case id="v3_type_pin" parent="v3">
|
<case id="v3_type_pin" parent="v3">
|
||||||
<passwordType>GeneratedPIN</passwordType>
|
<resultType>GeneratedPIN</resultType>
|
||||||
<result>7662</result>
|
<result>7662</result>
|
||||||
</case>
|
</case>
|
||||||
<case id="v3_type_name" parent="v3">
|
<case id="v3_type_name" parent="v3">
|
||||||
<passwordType>GeneratedName</passwordType>
|
<resultType>GeneratedName</resultType>
|
||||||
<result>jejraquvo</result>
|
<result>jejraquvo</result>
|
||||||
</case>
|
</case>
|
||||||
<case id="v3_type_phrase" parent="v3">
|
<case id="v3_type_phrase" parent="v3">
|
||||||
<passwordType>GeneratedPhrase</passwordType>
|
<resultType>GeneratedPhrase</resultType>
|
||||||
<result>jejr quv cabsibu tam</result>
|
<result>jejr quv cabsibu tam</result>
|
||||||
</case>
|
</case>
|
||||||
<case id="v3_counter_ceiling" parent="v3">
|
<case id="v3_counter_ceiling" parent="v3">
|
||||||
@ -99,12 +99,12 @@
|
|||||||
</case>
|
</case>
|
||||||
<case id="v2_loginName" parent="v2">
|
<case id="v2_loginName" parent="v2">
|
||||||
<keyPurpose>Identification</keyPurpose>
|
<keyPurpose>Identification</keyPurpose>
|
||||||
<passwordType>GeneratedName</passwordType>
|
<resultType>GeneratedName</resultType>
|
||||||
<result>wohzaqage</result>
|
<result>wohzaqage</result>
|
||||||
</case>
|
</case>
|
||||||
<case id="v2_securityAnswer" parent="v2">
|
<case id="v2_securityAnswer" parent="v2">
|
||||||
<keyPurpose>Recovery</keyPurpose>
|
<keyPurpose>Recovery</keyPurpose>
|
||||||
<passwordType>GeneratedPhrase</passwordType>
|
<resultType>GeneratedPhrase</resultType>
|
||||||
<result>xin diyjiqoja hubu</result>
|
<result>xin diyjiqoja hubu</result>
|
||||||
</case>
|
</case>
|
||||||
<case id="v2_securityAnswer_context" parent="v2_securityAnswer">
|
<case id="v2_securityAnswer_context" parent="v2_securityAnswer">
|
||||||
@ -112,31 +112,31 @@
|
|||||||
<result>xogx tem cegyiva jab</result>
|
<result>xogx tem cegyiva jab</result>
|
||||||
</case>
|
</case>
|
||||||
<case id="v2_type_maximum" parent="v2">
|
<case id="v2_type_maximum" parent="v2">
|
||||||
<passwordType>GeneratedMaximum</passwordType>
|
<resultType>GeneratedMaximum</resultType>
|
||||||
<result>W6@692^B1#&@gVdSdLZ@</result>
|
<result>W6@692^B1#&@gVdSdLZ@</result>
|
||||||
</case>
|
</case>
|
||||||
<case id="v2_type_medium" parent="v2">
|
<case id="v2_type_medium" parent="v2">
|
||||||
<passwordType>GeneratedMedium</passwordType>
|
<resultType>GeneratedMedium</resultType>
|
||||||
<result>Jej2$Quv</result>
|
<result>Jej2$Quv</result>
|
||||||
</case>
|
</case>
|
||||||
<case id="v2_type_basic" parent="v2">
|
<case id="v2_type_basic" parent="v2">
|
||||||
<passwordType>GeneratedBasic</passwordType>
|
<resultType>GeneratedBasic</resultType>
|
||||||
<result>WAo2xIg6</result>
|
<result>WAo2xIg6</result>
|
||||||
</case>
|
</case>
|
||||||
<case id="v2_type_short" parent="v2">
|
<case id="v2_type_short" parent="v2">
|
||||||
<passwordType>GeneratedShort</passwordType>
|
<resultType>GeneratedShort</resultType>
|
||||||
<result>Jej2</result>
|
<result>Jej2</result>
|
||||||
</case>
|
</case>
|
||||||
<case id="v2_type_pin" parent="v2">
|
<case id="v2_type_pin" parent="v2">
|
||||||
<passwordType>GeneratedPIN</passwordType>
|
<resultType>GeneratedPIN</resultType>
|
||||||
<result>7662</result>
|
<result>7662</result>
|
||||||
</case>
|
</case>
|
||||||
<case id="v2_type_name" parent="v2">
|
<case id="v2_type_name" parent="v2">
|
||||||
<passwordType>GeneratedName</passwordType>
|
<resultType>GeneratedName</resultType>
|
||||||
<result>jejraquvo</result>
|
<result>jejraquvo</result>
|
||||||
</case>
|
</case>
|
||||||
<case id="v2_type_phrase" parent="v2">
|
<case id="v2_type_phrase" parent="v2">
|
||||||
<passwordType>GeneratedPhrase</passwordType>
|
<resultType>GeneratedPhrase</resultType>
|
||||||
<result>jejr quv cabsibu tam</result>
|
<result>jejr quv cabsibu tam</result>
|
||||||
</case>
|
</case>
|
||||||
<case id="v2_counter_ceiling" parent="v2">
|
<case id="v2_counter_ceiling" parent="v2">
|
||||||
@ -165,12 +165,12 @@
|
|||||||
</case>
|
</case>
|
||||||
<case id="v1_loginName" parent="v1">
|
<case id="v1_loginName" parent="v1">
|
||||||
<keyPurpose>Identification</keyPurpose>
|
<keyPurpose>Identification</keyPurpose>
|
||||||
<passwordType>GeneratedName</passwordType>
|
<resultType>GeneratedName</resultType>
|
||||||
<result>wohzaqage</result>
|
<result>wohzaqage</result>
|
||||||
</case>
|
</case>
|
||||||
<case id="v1_securityAnswer" parent="v1">
|
<case id="v1_securityAnswer" parent="v1">
|
||||||
<keyPurpose>Recovery</keyPurpose>
|
<keyPurpose>Recovery</keyPurpose>
|
||||||
<passwordType>GeneratedPhrase</passwordType>
|
<resultType>GeneratedPhrase</resultType>
|
||||||
<result>xin diyjiqoja hubu</result>
|
<result>xin diyjiqoja hubu</result>
|
||||||
</case>
|
</case>
|
||||||
<case id="v1_securityAnswer_context" parent="v1_securityAnswer">
|
<case id="v1_securityAnswer_context" parent="v1_securityAnswer">
|
||||||
@ -178,31 +178,31 @@
|
|||||||
<result>xogx tem cegyiva jab</result>
|
<result>xogx tem cegyiva jab</result>
|
||||||
</case>
|
</case>
|
||||||
<case id="v1_type_maximum" parent="v1">
|
<case id="v1_type_maximum" parent="v1">
|
||||||
<passwordType>GeneratedMaximum</passwordType>
|
<resultType>GeneratedMaximum</resultType>
|
||||||
<result>W6@692^B1#&@gVdSdLZ@</result>
|
<result>W6@692^B1#&@gVdSdLZ@</result>
|
||||||
</case>
|
</case>
|
||||||
<case id="v1_type_medium" parent="v1">
|
<case id="v1_type_medium" parent="v1">
|
||||||
<passwordType>GeneratedMedium</passwordType>
|
<resultType>GeneratedMedium</resultType>
|
||||||
<result>Jej2$Quv</result>
|
<result>Jej2$Quv</result>
|
||||||
</case>
|
</case>
|
||||||
<case id="v1_type_basic" parent="v1">
|
<case id="v1_type_basic" parent="v1">
|
||||||
<passwordType>GeneratedBasic</passwordType>
|
<resultType>GeneratedBasic</resultType>
|
||||||
<result>WAo2xIg6</result>
|
<result>WAo2xIg6</result>
|
||||||
</case>
|
</case>
|
||||||
<case id="v1_type_short" parent="v1">
|
<case id="v1_type_short" parent="v1">
|
||||||
<passwordType>GeneratedShort</passwordType>
|
<resultType>GeneratedShort</resultType>
|
||||||
<result>Jej2</result>
|
<result>Jej2</result>
|
||||||
</case>
|
</case>
|
||||||
<case id="v1_type_pin" parent="v1">
|
<case id="v1_type_pin" parent="v1">
|
||||||
<passwordType>GeneratedPIN</passwordType>
|
<resultType>GeneratedPIN</resultType>
|
||||||
<result>7662</result>
|
<result>7662</result>
|
||||||
</case>
|
</case>
|
||||||
<case id="v1_type_name" parent="v1">
|
<case id="v1_type_name" parent="v1">
|
||||||
<passwordType>GeneratedName</passwordType>
|
<resultType>GeneratedName</resultType>
|
||||||
<result>jejraquvo</result>
|
<result>jejraquvo</result>
|
||||||
</case>
|
</case>
|
||||||
<case id="v1_type_phrase" parent="v1">
|
<case id="v1_type_phrase" parent="v1">
|
||||||
<passwordType>GeneratedPhrase</passwordType>
|
<resultType>GeneratedPhrase</resultType>
|
||||||
<result>jejr quv cabsibu tam</result>
|
<result>jejr quv cabsibu tam</result>
|
||||||
</case>
|
</case>
|
||||||
<case id="v1_counter_ceiling" parent="v1">
|
<case id="v1_counter_ceiling" parent="v1">
|
||||||
@ -231,12 +231,12 @@
|
|||||||
</case>
|
</case>
|
||||||
<case id="v0_loginName" parent="v0">
|
<case id="v0_loginName" parent="v0">
|
||||||
<keyPurpose>Identification</keyPurpose>
|
<keyPurpose>Identification</keyPurpose>
|
||||||
<passwordType>GeneratedName</passwordType>
|
<resultType>GeneratedName</resultType>
|
||||||
<result>lozwajave</result>
|
<result>lozwajave</result>
|
||||||
</case>
|
</case>
|
||||||
<case id="v0_securityAnswer" parent="v0">
|
<case id="v0_securityAnswer" parent="v0">
|
||||||
<keyPurpose>Recovery</keyPurpose>
|
<keyPurpose>Recovery</keyPurpose>
|
||||||
<passwordType>GeneratedPhrase</passwordType>
|
<resultType>GeneratedPhrase</resultType>
|
||||||
<result>miy lirfijoja dubu</result>
|
<result>miy lirfijoja dubu</result>
|
||||||
</case>
|
</case>
|
||||||
<case id="v0_securityAnswer_context" parent="v0_securityAnswer">
|
<case id="v0_securityAnswer_context" parent="v0_securityAnswer">
|
||||||
@ -244,31 +244,31 @@
|
|||||||
<result>movm bex gevrica jaf</result>
|
<result>movm bex gevrica jaf</result>
|
||||||
</case>
|
</case>
|
||||||
<case id="v0_type_maximum" parent="v0">
|
<case id="v0_type_maximum" parent="v0">
|
||||||
<passwordType>GeneratedMaximum</passwordType>
|
<resultType>GeneratedMaximum</resultType>
|
||||||
<result>w1!3bA3icmRAc)SS@lwl</result>
|
<result>w1!3bA3icmRAc)SS@lwl</result>
|
||||||
</case>
|
</case>
|
||||||
<case id="v0_type_medium" parent="v0">
|
<case id="v0_type_medium" parent="v0">
|
||||||
<passwordType>GeneratedMedium</passwordType>
|
<resultType>GeneratedMedium</resultType>
|
||||||
<result>Fej7]Jug</result>
|
<result>Fej7]Jug</result>
|
||||||
</case>
|
</case>
|
||||||
<case id="v0_type_basic" parent="v0">
|
<case id="v0_type_basic" parent="v0">
|
||||||
<passwordType>GeneratedBasic</passwordType>
|
<resultType>GeneratedBasic</resultType>
|
||||||
<result>wvH7irC1</result>
|
<result>wvH7irC1</result>
|
||||||
</case>
|
</case>
|
||||||
<case id="v0_type_short" parent="v0">
|
<case id="v0_type_short" parent="v0">
|
||||||
<passwordType>GeneratedShort</passwordType>
|
<resultType>GeneratedShort</resultType>
|
||||||
<result>Fej7</result>
|
<result>Fej7</result>
|
||||||
</case>
|
</case>
|
||||||
<case id="v0_type_pin" parent="v0">
|
<case id="v0_type_pin" parent="v0">
|
||||||
<passwordType>GeneratedPIN</passwordType>
|
<resultType>GeneratedPIN</resultType>
|
||||||
<result>2117</result>
|
<result>2117</result>
|
||||||
</case>
|
</case>
|
||||||
<case id="v0_type_name" parent="v0">
|
<case id="v0_type_name" parent="v0">
|
||||||
<passwordType>GeneratedName</passwordType>
|
<resultType>GeneratedName</resultType>
|
||||||
<result>fejrajugo</result>
|
<result>fejrajugo</result>
|
||||||
</case>
|
</case>
|
||||||
<case id="v0_type_phrase" parent="v0">
|
<case id="v0_type_phrase" parent="v0">
|
||||||
<passwordType>GeneratedPhrase</passwordType>
|
<resultType>GeneratedPhrase</resultType>
|
||||||
<result>fejr jug gabsibu bax</result>
|
<result>fejr jug gabsibu bax</result>
|
||||||
</case>
|
</case>
|
||||||
<case id="v0_counter_ceiling" parent="v0">
|
<case id="v0_counter_ceiling" parent="v0">
|
||||||
|
@ -50,7 +50,7 @@ int main(int argc, char *const argv[]) {
|
|||||||
const char *masterPassword = "banana colored duckling";
|
const char *masterPassword = "banana colored duckling";
|
||||||
const char *siteName = "masterpasswordapp.com";
|
const char *siteName = "masterpasswordapp.com";
|
||||||
const MPCounterValue siteCounter = MPCounterValueDefault;
|
const MPCounterValue siteCounter = MPCounterValueDefault;
|
||||||
const MPPasswordType passwordType = MPPasswordTypeDefault;
|
const MPResultType resultType = MPResultTypeDefault;
|
||||||
const MPKeyPurpose keyPurpose = MPKeyPurposeAuthentication;
|
const MPKeyPurpose keyPurpose = MPKeyPurposeAuthentication;
|
||||||
const char *keyContext = NULL;
|
const char *keyContext = NULL;
|
||||||
struct timeval startTime;
|
struct timeval startTime;
|
||||||
@ -69,7 +69,7 @@ int main(int argc, char *const argv[]) {
|
|||||||
}
|
}
|
||||||
mpw_getTime( &startTime );
|
mpw_getTime( &startTime );
|
||||||
for (int i = 1; i <= iterations; ++i) {
|
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)
|
if (modff(100.f * i / iterations, &percent) == 0)
|
||||||
fprintf( stderr, "\rhmac-sha-256: iteration %d / %d (%.0f%%)..", i, iterations, percent );
|
fprintf( stderr, "\rhmac-sha-256: iteration %d / %d (%.0f%%)..", i, iterations, percent );
|
||||||
@ -113,12 +113,9 @@ int main(int argc, char *const argv[]) {
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
MPSiteKey siteKey = mpw_siteKey(
|
free( (void *)mpw_siteResult(
|
||||||
masterKey, siteName, siteCounter, keyPurpose, keyContext, MPAlgorithmVersionCurrent );
|
masterKey, siteName, siteCounter, keyPurpose, keyContext, resultType, NULL, MPAlgorithmVersionCurrent ) );
|
||||||
free( (void *)mpw_sitePassword(
|
|
||||||
siteKey, passwordType, MPAlgorithmVersionCurrent ) );
|
|
||||||
free( (void *)masterKey );
|
free( (void *)masterKey );
|
||||||
free( (void *)siteKey );
|
|
||||||
|
|
||||||
if (modff(100.f * i / iterations, &percent) == 0)
|
if (modff(100.f * i / iterations, &percent) == 0)
|
||||||
fprintf( stderr, "\rmpw: iteration %d / %d (%.0f%%)..", i, iterations, percent );
|
fprintf( stderr, "\rmpw: iteration %d / %d (%.0f%%)..", i, iterations, percent );
|
||||||
|
@ -47,7 +47,8 @@ static void usage() {
|
|||||||
" i, pin | 4 numbers.\n"
|
" i, pin | 4 numbers.\n"
|
||||||
" n, name | 9 letter name.\n"
|
" n, name | 9 letter name.\n"
|
||||||
" p, phrase | 20 character sentence.\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( ""
|
inf( ""
|
||||||
" -c counter The value of the counter.\n"
|
" -c counter The value of the counter.\n"
|
||||||
" Defaults to 1.\n\n" );
|
" Defaults to 1.\n\n" );
|
||||||
@ -56,7 +57,8 @@ static void usage() {
|
|||||||
" Defaults to %s in env or %d.\n\n",
|
" Defaults to %s in env or %d.\n\n",
|
||||||
MPAlgorithmVersionFirst, MPAlgorithmVersionLast, MP_ENV_algorithm, MPAlgorithmVersionCurrent );
|
MPAlgorithmVersionFirst, MPAlgorithmVersionLast, MP_ENV_algorithm, MPAlgorithmVersionCurrent );
|
||||||
inf( ""
|
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( ""
|
inf( ""
|
||||||
" -p purpose The purpose of the generated token.\n"
|
" -p purpose The purpose of the generated token.\n"
|
||||||
" Defaults to 'auth'.\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[]) {
|
int main(int argc, char *const argv[]) {
|
||||||
|
|
||||||
// Master Password defaults.
|
// 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;
|
MPCounterValue siteCounter = MPCounterValueDefault;
|
||||||
MPPasswordType passwordType = MPPasswordTypeDefault;
|
MPResultType resultType = MPResultTypeDefault;
|
||||||
MPKeyPurpose keyPurpose = MPKeyPurposeAuthentication;
|
MPKeyPurpose keyPurpose = MPKeyPurposeAuthentication;
|
||||||
MPAlgorithmVersion algorithmVersion = MPAlgorithmVersionCurrent;
|
MPAlgorithmVersion algorithmVersion = MPAlgorithmVersionCurrent;
|
||||||
MPMarshallFormat sitesFormat = MPMarshallFormatDefault;
|
MPMarshallFormat sitesFormat = MPMarshallFormatDefault;
|
||||||
@ -160,13 +162,13 @@ int main(int argc, char *const argv[]) {
|
|||||||
|
|
||||||
// Read the environment.
|
// Read the environment.
|
||||||
const char *fullNameArg = NULL, *masterPasswordArg = NULL, *siteNameArg = NULL;
|
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;
|
const char *keyPurposeArg = NULL, *keyContextArg = NULL, *sitesFormatArg = NULL, *sitesRedactedArg = NULL;
|
||||||
fullNameArg = mpw_getenv( MP_ENV_fullName );
|
fullNameArg = mpw_getenv( MP_ENV_fullName );
|
||||||
algorithmVersionArg = mpw_getenv( MP_ENV_algorithm );
|
algorithmVersionArg = mpw_getenv( MP_ENV_algorithm );
|
||||||
|
|
||||||
// Read the command-line options.
|
// 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) {
|
switch (opt) {
|
||||||
case 'u':
|
case 'u':
|
||||||
fullNameArg = optarg && strlen( optarg )? strdup( optarg ): NULL;
|
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;
|
fullNameArg = optarg && strlen( optarg )? strdup( optarg ): NULL;
|
||||||
allowPasswordUpdate = true;
|
allowPasswordUpdate = true;
|
||||||
break;
|
break;
|
||||||
case 'P':
|
case 'M':
|
||||||
// Passing your master password via the command-line is insecure. Testing purposes only.
|
// Passing your master password via the command-line is insecure. Testing purposes only.
|
||||||
masterPasswordArg = optarg && strlen( optarg )? strdup( optarg ): NULL;
|
masterPasswordArg = optarg && strlen( optarg )? strdup( optarg ): NULL;
|
||||||
break;
|
break;
|
||||||
case 't':
|
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;
|
break;
|
||||||
case 'c':
|
case 'c':
|
||||||
siteCounterArg = optarg && strlen( optarg )? strdup( optarg ): NULL;
|
siteCounterArg = optarg && strlen( optarg )? strdup( optarg ): NULL;
|
||||||
@ -189,9 +194,6 @@ int main(int argc, char *const argv[]) {
|
|||||||
case 'a':
|
case 'a':
|
||||||
algorithmVersionArg = optarg && strlen( optarg )? strdup( optarg ): NULL;
|
algorithmVersionArg = optarg && strlen( optarg )? strdup( optarg ): NULL;
|
||||||
break;
|
break;
|
||||||
case 's':
|
|
||||||
saveValueArg = optarg && strlen( optarg )? strdup( optarg ): NULL;
|
|
||||||
break;
|
|
||||||
case 'p':
|
case 'p':
|
||||||
keyPurposeArg = optarg && strlen( optarg )? strdup( optarg ): NULL;
|
keyPurposeArg = optarg && strlen( optarg )? strdup( optarg ): NULL;
|
||||||
break;
|
break;
|
||||||
@ -342,7 +344,7 @@ int main(int argc, char *const argv[]) {
|
|||||||
fullName = strdup( user->fullName );
|
fullName = strdup( user->fullName );
|
||||||
masterPassword = strdup( user->masterPassword );
|
masterPassword = strdup( user->masterPassword );
|
||||||
algorithmVersion = user->algorithm;
|
algorithmVersion = user->algorithm;
|
||||||
passwordType = user->defaultType;
|
resultType = user->defaultType;
|
||||||
sitesRedacted = user->redacted;
|
sitesRedacted = user->redacted;
|
||||||
|
|
||||||
if (!sitesRedacted && !sitesRedactedArg)
|
if (!sitesRedacted && !sitesRedactedArg)
|
||||||
@ -355,8 +357,8 @@ int main(int argc, char *const argv[]) {
|
|||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
mpw_free_string( saveValue );
|
mpw_free_string( resultParam );
|
||||||
passwordType = site->type;
|
resultType = site->type;
|
||||||
siteCounter = site->counter;
|
siteCounter = site->counter;
|
||||||
algorithmVersion = site->algorithm;
|
algorithmVersion = site->algorithm;
|
||||||
break;
|
break;
|
||||||
@ -383,10 +385,6 @@ int main(int argc, char *const argv[]) {
|
|||||||
}
|
}
|
||||||
algorithmVersion = (MPAlgorithmVersion)algorithmVersionInt;
|
algorithmVersion = (MPAlgorithmVersion)algorithmVersionInt;
|
||||||
}
|
}
|
||||||
if (saveValueArg) {
|
|
||||||
mpw_free_string( saveValue );
|
|
||||||
saveValue = strdup( saveValueArg );
|
|
||||||
}
|
|
||||||
if (keyPurposeArg) {
|
if (keyPurposeArg) {
|
||||||
keyPurpose = mpw_purposeWithName( keyPurposeArg );
|
keyPurpose = mpw_purposeWithName( keyPurposeArg );
|
||||||
if (ERR == (int)keyPurpose) {
|
if (ERR == (int)keyPurpose) {
|
||||||
@ -399,23 +397,27 @@ int main(int argc, char *const argv[]) {
|
|||||||
case MPKeyPurposeAuthentication:
|
case MPKeyPurposeAuthentication:
|
||||||
break;
|
break;
|
||||||
case MPKeyPurposeIdentification: {
|
case MPKeyPurposeIdentification: {
|
||||||
passwordType = MPPasswordTypeGeneratedName;
|
resultType = MPResultTypeTemplateName;
|
||||||
purposeResult = "login";
|
purposeResult = "login";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
case MPKeyPurposeRecovery: {
|
case MPKeyPurposeRecovery: {
|
||||||
passwordType = MPPasswordTypeGeneratedPhrase;
|
resultType = MPResultTypeTemplatePhrase;
|
||||||
purposeResult = "answer";
|
purposeResult = "answer";
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (passwordTypeArg) {
|
if (resultTypeArg) {
|
||||||
passwordType = mpw_typeWithName( passwordTypeArg );
|
resultType = mpw_typeWithName( resultTypeArg );
|
||||||
if (ERR == (int)passwordType) {
|
if (ERR == (int)resultType) {
|
||||||
ftl( "Invalid type: %s\n", passwordTypeArg );
|
ftl( "Invalid type: %s\n", resultTypeArg );
|
||||||
return EX_USAGE;
|
return EX_USAGE;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (resultParamArg) {
|
||||||
|
mpw_free_string( resultParam );
|
||||||
|
resultParam = strdup( resultParamArg );
|
||||||
|
}
|
||||||
if (keyContextArg) {
|
if (keyContextArg) {
|
||||||
mpw_free_string( keyContext );
|
mpw_free_string( keyContext );
|
||||||
keyContext = strdup( keyContextArg );
|
keyContext = strdup( keyContextArg );
|
||||||
@ -423,10 +425,10 @@ int main(int argc, char *const argv[]) {
|
|||||||
mpw_free_string( fullNameArg );
|
mpw_free_string( fullNameArg );
|
||||||
mpw_free_string( masterPasswordArg );
|
mpw_free_string( masterPasswordArg );
|
||||||
mpw_free_string( siteNameArg );
|
mpw_free_string( siteNameArg );
|
||||||
mpw_free_string( passwordTypeArg );
|
mpw_free_string( resultTypeArg );
|
||||||
|
mpw_free_string( resultParamArg );
|
||||||
mpw_free_string( siteCounterArg );
|
mpw_free_string( siteCounterArg );
|
||||||
mpw_free_string( algorithmVersionArg );
|
mpw_free_string( algorithmVersionArg );
|
||||||
mpw_free_string( saveValueArg );
|
|
||||||
mpw_free_string( keyPurposeArg );
|
mpw_free_string( keyPurposeArg );
|
||||||
mpw_free_string( keyContextArg );
|
mpw_free_string( keyContextArg );
|
||||||
mpw_free_string( sitesFormatArg );
|
mpw_free_string( sitesFormatArg );
|
||||||
@ -444,10 +446,10 @@ int main(int argc, char *const argv[]) {
|
|||||||
dbg( "sitesPath : %s\n", sitesPath );
|
dbg( "sitesPath : %s\n", sitesPath );
|
||||||
dbg( "siteName : %s\n", siteName );
|
dbg( "siteName : %s\n", siteName );
|
||||||
dbg( "siteCounter : %u\n", siteCounter );
|
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( "keyPurpose : %s (%u)\n", mpw_nameForPurpose( keyPurpose ), keyPurpose );
|
||||||
dbg( "keyContext : %s\n", keyContext );
|
dbg( "keyContext : %s\n", keyContext );
|
||||||
dbg( "passwordType : %s (%u)\n", mpw_nameForType( passwordType ), passwordType );
|
|
||||||
dbg( "algorithmVersion : %u\n", algorithmVersion );
|
dbg( "algorithmVersion : %u\n", algorithmVersion );
|
||||||
dbg( "-----------------\n\n" );
|
dbg( "-----------------\n\n" );
|
||||||
inf( "%s's %s for %s:\n[ %s ]: ", fullName, purposeResult, siteName, identicon );
|
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)
|
if (keyPurpose == MPKeyPurposeIdentification && site && !site->loginGenerated && site->loginName)
|
||||||
fprintf( stdout, "%s\n", site->loginName );
|
fprintf( stdout, "%s\n", site->loginName );
|
||||||
|
|
||||||
else if (passwordType & MPPasswordTypeClassGenerated) {
|
else if (resultParam && site && resultType & MPResultTypeClassState) {
|
||||||
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" );
|
|
||||||
mpw_free( masterKey, MPMasterKeySize );
|
|
||||||
return EX_SOFTWARE;
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf( stdout, "%s\n", sitePassword );
|
|
||||||
mpw_free_string( sitePassword );
|
|
||||||
}
|
|
||||||
|
|
||||||
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 );
|
mpw_free_string( site->content );
|
||||||
if (!(site->content = mpw_encrypt( masterKey, saveValue, algorithmVersion )))
|
if (!(site->content = mpw_siteState( masterKey, siteName, siteCounter,
|
||||||
err( "Couldn't encrypt site content.\n" );
|
keyPurpose, keyContext, resultType, resultParam, algorithmVersion ))) {
|
||||||
}
|
ftl( "Couldn't encrypt site content.\n" );
|
||||||
}
|
|
||||||
|
|
||||||
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 );
|
mpw_free( masterKey, MPMasterKeySize );
|
||||||
return EX_SOFTWARE;
|
return EX_SOFTWARE;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inf( "saved.\n" );
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
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;
|
||||||
}
|
}
|
||||||
|
|
||||||
fprintf( stdout, "%s\n", content );
|
fprintf( stdout, "%s\n", siteResult );
|
||||||
mpw_free_string( content );
|
mpw_free_string( siteResult );
|
||||||
}
|
}
|
||||||
|
|
||||||
if (site && site->url)
|
if (site && site->url)
|
||||||
inf( "See: %s\n", site->url );
|
inf( "See: %s\n", site->url );
|
||||||
mpw_free( masterKey, MPMasterKeySize );
|
mpw_free( masterKey, MPMasterKeySize );
|
||||||
mpw_free_string( siteName );
|
mpw_free_string( siteName );
|
||||||
mpw_free_string( saveValue );
|
mpw_free_string( resultParam );
|
||||||
mpw_free_string( keyContext );
|
mpw_free_string( keyContext );
|
||||||
|
|
||||||
// Update the mpsites file.
|
// Update the mpsites file.
|
||||||
if (user) {
|
if (user) {
|
||||||
// TODO: Move this up above the summary and replace the mpw lvars by user/site accessors.
|
// 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)
|
if (!site)
|
||||||
site = mpw_marshall_site( user, siteName, passwordType, siteCounter, algorithmVersion );
|
site = mpw_marshall_site( user, siteName, resultType, siteCounter, algorithmVersion );
|
||||||
else {
|
else {
|
||||||
site->type = passwordType;
|
site->type = resultType;
|
||||||
site->counter = siteCounter;
|
site->counter = siteCounter;
|
||||||
site->algorithm = algorithmVersion;
|
site->algorithm = algorithmVersion;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (keyPurpose == MPKeyPurposeIdentification && site) {
|
else if (keyPurpose == MPKeyPurposeIdentification && site) {
|
||||||
// TODO: We're not persisting the passwordType of the generated login
|
// TODO: We're not persisting the resultType of the generated login
|
||||||
if (passwordType & MPPasswordTypeClassGenerated)
|
if (resultType & MPResultTypeClassTemplate)
|
||||||
site->loginGenerated = true;
|
site->loginGenerated = true;
|
||||||
}
|
}
|
||||||
else if (keyPurpose == MPKeyPurposeRecovery && site && keyContext) {
|
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;
|
MPMarshalledQuestion *question = NULL;
|
||||||
for (size_t q = 0; q < site->questions_count; ++q) {
|
for (size_t q = 0; q < site->questions_count; ++q) {
|
||||||
question = &site->questions[q];
|
question = &site->questions[q];
|
||||||
|
@ -30,13 +30,13 @@ int main(int argc, char *const argv[]) {
|
|||||||
xmlChar *keyID = mpw_xmlTestCaseString( testCase, "keyID" );
|
xmlChar *keyID = mpw_xmlTestCaseString( testCase, "keyID" );
|
||||||
xmlChar *siteName = mpw_xmlTestCaseString( testCase, "siteName" );
|
xmlChar *siteName = mpw_xmlTestCaseString( testCase, "siteName" );
|
||||||
MPCounterValue siteCounter = (MPCounterValue)mpw_xmlTestCaseInteger( testCase, "siteCounter" );
|
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 *keyPurposeString = mpw_xmlTestCaseString( testCase, "keyPurpose" );
|
||||||
xmlChar *keyContext = mpw_xmlTestCaseString( testCase, "keyContext" );
|
xmlChar *keyContext = mpw_xmlTestCaseString( testCase, "keyContext" );
|
||||||
xmlChar *result = mpw_xmlTestCaseString( testCase, "result" );
|
xmlChar *result = mpw_xmlTestCaseString( testCase, "result" );
|
||||||
|
|
||||||
MPPasswordType siteType = mpw_typeWithName( (char *)passwordTypeString );
|
MPResultType resultType = mpw_typeWithName( (char *)resultTypeString );
|
||||||
MPKeyPurpose siteVariant = mpw_purposeWithName( (char *)keyPurposeString );
|
MPKeyPurpose keyPurpose = mpw_purposeWithName( (char *)keyPurposeString );
|
||||||
|
|
||||||
// Run the test case.
|
// Run the test case.
|
||||||
fprintf( stdout, "test case %s... ", id );
|
fprintf( stdout, "test case %s... ", id );
|
||||||
@ -54,12 +54,9 @@ int main(int argc, char *const argv[]) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
// 2. calculate the site password.
|
// 2. calculate the site password.
|
||||||
MPSiteKey siteKey = mpw_siteKey(
|
const char *sitePassword = mpw_siteResult(
|
||||||
masterKey, (char *)siteName, siteCounter, siteVariant, (char *)keyContext, algorithm );
|
masterKey, (char *)siteName, siteCounter, keyPurpose, (char *)keyContext, resultType, NULL, algorithm );
|
||||||
const char *sitePassword = mpw_sitePassword(
|
|
||||||
siteKey, siteType, algorithm );
|
|
||||||
mpw_free( masterKey, MPMasterKeySize );
|
mpw_free( masterKey, MPMasterKeySize );
|
||||||
mpw_free( siteKey, MPSiteKeySize );
|
|
||||||
if (!sitePassword) {
|
if (!sitePassword) {
|
||||||
ftl( "Couldn't derive site password.\n" );
|
ftl( "Couldn't derive site password.\n" );
|
||||||
continue;
|
continue;
|
||||||
@ -81,7 +78,7 @@ int main(int argc, char *const argv[]) {
|
|||||||
xmlFree( masterPassword );
|
xmlFree( masterPassword );
|
||||||
xmlFree( keyID );
|
xmlFree( keyID );
|
||||||
xmlFree( siteName );
|
xmlFree( siteName );
|
||||||
xmlFree( passwordTypeString );
|
xmlFree( resultTypeString );
|
||||||
xmlFree( keyPurposeString );
|
xmlFree( keyPurposeString );
|
||||||
xmlFree( keyContext );
|
xmlFree( keyContext );
|
||||||
xmlFree( result );
|
xmlFree( result );
|
||||||
|
@ -5,7 +5,6 @@ cd "${BASH_SOURCE%/*}"
|
|||||||
tag=$(git describe --match '*-cli*')
|
tag=$(git describe --match '*-cli*')
|
||||||
commit=$(git describe --long --dirty --match '*-cli*')
|
commit=$(git describe --long --dirty --match '*-cli*')
|
||||||
[[ $commit != *-dirty ]] || { echo >&2 "Tree is dirty, first commit any changes."; exit 1; }
|
[[ $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
|
mpwArchive=mpw-$commit.tar.gz
|
||||||
[[ -e $mpwArchive ]] && echo >&2 "WARNING: $mpwArchive already exists. Will overwrite."
|
[[ -e $mpwArchive ]] && echo >&2 "WARNING: $mpwArchive already exists. Will overwrite."
|
||||||
@ -15,6 +14,7 @@ echo "Cleaning .."
|
|||||||
( git clean -ffdx . && cd core && git clean -ffdx . )
|
( git clean -ffdx . && cd core && git clean -ffdx . )
|
||||||
|
|
||||||
echo "Creating archive $mpwArchive .."
|
echo "Creating archive $mpwArchive .."
|
||||||
|
git show --show-signature --pretty=format:%H --quiet "$tag" > VERSION
|
||||||
git ls-files -z . | xargs -0 tar -Lcvzf "$mpwArchive"
|
git ls-files -z . | xargs -0 tar -Lcvzf "$mpwArchive"
|
||||||
|
|
||||||
echo "Creating archive signature $mpwArchive.sig .."
|
echo "Creating archive signature $mpwArchive.sig .."
|
||||||
|
Loading…
Reference in New Issue
Block a user