From 228f8e4ed132007907b85fe5e81539d1281512fd Mon Sep 17 00:00:00 2001 From: Maarten Billemont Date: Fri, 4 Aug 2017 10:43:46 -0400 Subject: [PATCH] C API for hybrid passwords. --- core/c/mpw-algorithm.c | 42 +++++++++++++++++++++++++++++++++++++++ core/c/mpw-algorithm.h | 10 ++++++++++ core/c/mpw-algorithm_v0.c | 12 +++++++++++ core/c/mpw-algorithm_v1.c | 12 +++++++++++ core/c/mpw-algorithm_v2.c | 12 +++++++++++ core/c/mpw-algorithm_v3.c | 12 +++++++++++ core/c/mpw-marshall.c | 30 ++++++++++++++-------------- 7 files changed, 115 insertions(+), 15 deletions(-) diff --git a/core/c/mpw-algorithm.c b/core/c/mpw-algorithm.c index 284fe703..35d4dd18 100644 --- a/core/c/mpw-algorithm.c +++ b/core/c/mpw-algorithm.c @@ -84,3 +84,45 @@ const char *mpw_sitePassword( return NULL; } } + +const char *mpw_encrypt( + MPMasterKey masterKey, const char *plainText, const MPAlgorithmVersion algorithmVersion) { + + if (!masterKey || !plainText) + return NULL; + + switch (algorithmVersion) { + case MPAlgorithmVersion0: + return mpw_encrypt_v0( masterKey, plainText ); + case MPAlgorithmVersion1: + return mpw_encrypt_v1( masterKey, plainText ); + case MPAlgorithmVersion2: + return mpw_encrypt_v2( masterKey, plainText ); + case MPAlgorithmVersion3: + return mpw_encrypt_v3( masterKey, plainText ); + default: + err( "Unsupported version: %d\n", algorithmVersion ); + return NULL; + } +} + +const char *mpw_decrypt( + MPMasterKey masterKey, const char *cipherText, const MPAlgorithmVersion algorithmVersion) { + + if (!masterKey || !cipherText) + return NULL; + + switch (algorithmVersion) { + case MPAlgorithmVersion0: + return mpw_decrypt_v0( masterKey, cipherText ); + case MPAlgorithmVersion1: + return mpw_decrypt_v1( masterKey, cipherText ); + case MPAlgorithmVersion2: + return mpw_decrypt_v2( masterKey, cipherText ); + case MPAlgorithmVersion3: + return mpw_decrypt_v3( masterKey, cipherText ); + default: + err( "Unsupported version: %d\n", algorithmVersion ); + return NULL; + } +} diff --git a/core/c/mpw-algorithm.h b/core/c/mpw-algorithm.h index 4695ac58..14cd7a33 100644 --- a/core/c/mpw-algorithm.h +++ b/core/c/mpw-algorithm.h @@ -53,4 +53,14 @@ MPSiteKey mpw_siteKey( const char *mpw_sitePassword( MPSiteKey siteKey, const MPPasswordType passwordType, const MPAlgorithmVersion algorithmVersion); +/** Perform symmetric encryption on a secret token's plainText. + * @return The newly allocated cipherText of the secret token encrypted by the masterKey. */ +const char *mpw_encrypt( + MPMasterKey masterKey, const char *plainText, const MPAlgorithmVersion algorithmVersion); + +/** Perform symmetric decryption on a secret token's cipherText. + * @return The newly allocated plainText of the secret token decrypted by the masterKey. */ +const char *mpw_decrypt( + MPMasterKey masterKey, const char *cipherText, const MPAlgorithmVersion algorithmVersion); + #endif // _MPW_ALGORITHM_H diff --git a/core/c/mpw-algorithm_v0.c b/core/c/mpw-algorithm_v0.c index ab6263f2..5e755769 100644 --- a/core/c/mpw-algorithm_v0.c +++ b/core/c/mpw-algorithm_v0.c @@ -151,3 +151,15 @@ static const char *mpw_sitePassword_v0( return sitePassword; } + +const char *mpw_encrypt_v0( + MPMasterKey masterKey, const char *plainText) { + + return NULL; // TODO: aes128_cbc +} + +const char *mpw_decrypt_v0( + MPMasterKey masterKey, const char *cipherText) { + + return NULL; // TODO: aes128_cbc +} diff --git a/core/c/mpw-algorithm_v1.c b/core/c/mpw-algorithm_v1.c index 34f9a713..6fc1fbb9 100644 --- a/core/c/mpw-algorithm_v1.c +++ b/core/c/mpw-algorithm_v1.c @@ -132,3 +132,15 @@ static const char *mpw_sitePassword_v1( return sitePassword; } + +const char *mpw_encrypt_v1( + MPMasterKey masterKey, const char *plainText) { + + return NULL; // TODO: aes128_cbc +} + +const char *mpw_decrypt_v1( + MPMasterKey masterKey, const char *cipherText) { + + return NULL; // TODO: aes128_cbc +} diff --git a/core/c/mpw-algorithm_v2.c b/core/c/mpw-algorithm_v2.c index 23de9419..49766e17 100644 --- a/core/c/mpw-algorithm_v2.c +++ b/core/c/mpw-algorithm_v2.c @@ -132,3 +132,15 @@ static const char *mpw_sitePassword_v2( return sitePassword; } + +const char *mpw_encrypt_v2( + MPMasterKey masterKey, const char *plainText) { + + return NULL; // TODO: aes128_cbc +} + +const char *mpw_decrypt_v2( + MPMasterKey masterKey, const char *cipherText) { + + return NULL; // TODO: aes128_cbc +} diff --git a/core/c/mpw-algorithm_v3.c b/core/c/mpw-algorithm_v3.c index ae5722e0..d2043111 100644 --- a/core/c/mpw-algorithm_v3.c +++ b/core/c/mpw-algorithm_v3.c @@ -132,3 +132,15 @@ static const char *mpw_sitePassword_v3( return sitePassword; } + +const char *mpw_encrypt_v3( + MPMasterKey masterKey, const char *plainText) { + + return NULL; // TODO: aes128_cbc +} + +const char *mpw_decrypt_v3( + MPMasterKey masterKey, const char *cipherText) { + + return NULL; // TODO: aes128_cbc +} diff --git a/core/c/mpw-marshall.c b/core/c/mpw-marshall.c index a9d62a2a..ab7eb2e2 100644 --- a/core/c/mpw-marshall.c +++ b/core/c/mpw-marshall.c @@ -159,7 +159,7 @@ static bool mpw_marshall_write_flat( if (!site.name || !strlen( site.name )) continue; - const char *content = site.type & MPSiteFeatureExportContent? site.content: NULL; + const char *content = NULL; if (!user->redacted) { if (!mpw_update_masterKey( &masterKey, &masterKeyAlgorithm, site.algorithm, user->name, user->masterPassword )) { *error = (MPMarshallError){ MPMarshallErrorInternal, "Couldn't derive master key." }; @@ -171,16 +171,16 @@ static bool mpw_marshall_write_flat( content = mpw_sitePassword( siteKey, site.type, site.algorithm ); mpw_free( siteKey, MPSiteKeySize ); } - else if (content) { - // TODO: Decrypt Personal Passwords - //content = aes128_cbc( masterKey, content ); - } - } + 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 )) + content = strdup( site.content ); if (strftime( dateString, sizeof( dateString ), "%FT%TZ", gmtime( &site.lastUsed ) )) mpw_string_pushf( out, "%s %8ld %lu:%lu:%lu %25s\t%25s\t%s\n", dateString, (long)site.uses, (long)site.type, (long)site.algorithm, (long)site.counter, site.loginName?: "", site.name, content?: "" ); + mpw_free_string( content ); } mpw_free( masterKey, MPMasterKeySize ); @@ -240,7 +240,7 @@ static bool mpw_marshall_write_json( if (!site.name || !strlen( site.name )) continue; - const char *content = site.type & MPSiteFeatureExportContent? site.content: NULL; + const char *content = NULL; if (!user->redacted) { if (!mpw_update_masterKey( &masterKey, &masterKeyAlgorithm, site.algorithm, user->name, user->masterPassword )) { *error = (MPMarshallError){ MPMarshallErrorInternal, "Couldn't derive master key." }; @@ -252,11 +252,11 @@ static bool mpw_marshall_write_json( content = mpw_sitePassword( siteKey, site.type, site.algorithm ); mpw_free( siteKey, MPSiteKeySize ); } - else if (content) { - // TODO: Decrypt Personal Passwords - //content = aes128_cbc( masterKey, content ); - } + 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 )) + content = strdup( site.content ); json_object *json_site = json_object_new_object(); json_object_object_add( json_sites, site.name, json_site ); @@ -296,6 +296,8 @@ static bool mpw_marshall_write_json( json_object_object_add( json_site, "_ext_mpw", json_site_mpw ); if (site.url) json_object_object_add( json_site_mpw, "url", json_object_new_string( site.url ) ); + + mpw_free_string( content ); } mpw_string_pushf( out, "%s\n", json_object_to_json_string_ext( json_file, JSON_C_TO_STRING_PRETTY | JSON_C_TO_STRING_SPACED ) ); @@ -504,8 +506,7 @@ static MPMarshalledUser *mpw_marshall_read_flat( return NULL; } - // TODO: Encrypt Personal Passwords - //site->content = aes128_cbc( masterKey, exportContent ); + site->content = mpw_encrypt( masterKey, siteContent, site->algorithm ); } else site->content = strdup( siteContent ); @@ -658,8 +659,7 @@ static MPMarshalledUser *mpw_marshall_read_json( return NULL; } - // TODO: Encrypt Personal Passwords - //site->content = aes128_cbc( masterKey, exportContent ); + site->content = mpw_encrypt( masterKey, siteContent, site->algorithm ); } else site->content = strdup( siteContent );