2
0

Standardize on a naming scheme: cipher -> template, userName -> fullName, element -> site.

This commit is contained in:
Maarten Billemont 2014-12-05 17:56:50 -05:00
parent b976e79b0f
commit 3f4558da2b
19 changed files with 187 additions and 238 deletions

View File

@ -33,7 +33,7 @@ else
# Modify here or override using targets='mpw mpw-bench' ./build
targets=(
mpw # C CLI version of Master Password.
#mpw-bench # C CLI Master Password benchmark utility.
mpw-bench # C CLI Master Password benchmark utility.
)
fi

View File

@ -25,11 +25,11 @@
int main(int argc, char *const argv[]) {
char *userName = "Robert Lee Mitchel";
char *fullName = "Robert Lee Mitchel";
char *masterPassword = "banana colored duckling";
char *siteName = "masterpasswordapp.com";
uint32_t siteCounter = 1;
MPElementType siteType = MPElementTypeGeneratedLong;
MPSiteType siteType = MPSiteTypeGeneratedLong;
// Start MP
struct timeval startTime;
@ -42,8 +42,8 @@ int main(int argc, char *const argv[]) {
for (int i = 0; i < iterations; ++i) {
// Calculate the master key salt.
char *mpNameSpace = "com.lyndir.masterpassword";
const uint32_t n_userNameLength = htonl(strlen(userName));
const size_t masterKeySaltLength = strlen(mpNameSpace) + sizeof(n_userNameLength) + strlen(userName);
const uint32_t n_fullNameLength = htonl(strlen(fullName));
const size_t masterKeySaltLength = strlen(mpNameSpace) + sizeof(n_fullNameLength) + strlen(fullName);
char *masterKeySalt = malloc( masterKeySaltLength );
if (!masterKeySalt) {
fprintf(stderr, "Could not allocate master key salt: %d\n", errno);
@ -52,8 +52,8 @@ int main(int argc, char *const argv[]) {
char *mKS = masterKeySalt;
memcpy(mKS, mpNameSpace, strlen(mpNameSpace)); mKS += strlen(mpNameSpace);
memcpy(mKS, &n_userNameLength, sizeof(n_userNameLength)); mKS += sizeof(n_userNameLength);
memcpy(mKS, userName, strlen(userName)); mKS += strlen(userName);
memcpy(mKS, &n_fullNameLength, sizeof(n_fullNameLength)); mKS += sizeof(n_fullNameLength);
memcpy(mKS, fullName, strlen(fullName)); mKS += strlen(fullName);
if (mKS - masterKeySalt != masterKeySaltLength)
abort();
trc("masterKeySalt ID: %s\n", IDForBuf(masterKeySalt, masterKeySaltLength));
@ -96,17 +96,17 @@ int main(int argc, char *const argv[]) {
free(masterKey);
free(sitePasswordInfo);
// Determine the cipher.
const char *cipher = CipherForType(siteType, sitePasswordSeed[0]);
trc("type %d, cipher: %s\n", siteType, cipher);
if (strlen(cipher) > 32)
// Determine the template.
const char *template = TemplateForType(siteType, sitePasswordSeed[0]);
trc("type %d, template: %s\n", siteType, template);
if (strlen(template) > 32)
abort();
// Encode the password from the seed using the cipher.
char *sitePassword = calloc(strlen(cipher) + 1, sizeof(char));
for (int c = 0; c < strlen(cipher); ++c) {
sitePassword[c] = CharacterFromClass(cipher[c], sitePasswordSeed[c + 1]);
trc("class %c, character: %c\n", cipher[c], sitePassword[c]);
// Encode the password from the seed using the template.
char *sitePassword = calloc(strlen(template) + 1, sizeof(char));
for (int c = 0; c < strlen(template); ++c) {
sitePassword[c] = CharacterFromClass(template[c], sitePasswordSeed[c + 1]);
trc("class %c, character: %c\n", template[c], sitePassword[c]);
}
memset(sitePasswordSeed, 0, sizeof(sitePasswordSeed));
@ -161,7 +161,7 @@ int main(int argc, char *const argv[]) {
int bcrypt_cost = 9;
iterations = 600;
for (int i = 0; i < iterations; ++i) {
crypt(masterPassword, crypt_gensalt("$2b$", bcrypt_cost, userName, strlen(userName)));
crypt(masterPassword, crypt_gensalt("$2b$", bcrypt_cost, fullName, strlen(fullName)));
if (i % 10 == 0)
fprintf( stderr, "\rbcrypt (cost %d): iteration %d / %d..", bcrypt_cost, i, iterations );

View File

@ -35,14 +35,14 @@
#define MP_dkLen 64
#define MP_hash PearlHashSHA256
#define MP_env_username "MP_USERNAME"
#define MP_env_fullname "MP_FULLNAME"
#define MP_env_sitetype "MP_SITETYPE"
#define MP_env_sitecounter "MP_SITECOUNTER"
void usage() {
fprintf(stderr, "Usage: mpw [-u name] [-t type] [-c counter] site\n\n");
fprintf(stderr, " -u name Specify the full name of the user.\n"
" Defaults to %s in env.\n\n", MP_env_username);
" Defaults to %s in env.\n\n", MP_env_fullname);
fprintf(stderr, " -t type Specify the password's template.\n"
" Defaults to %s in env or 'long' for password, 'name' for login.\n"
" x, max, maximum | 20 characters, contains symbols.\n"
@ -67,7 +67,7 @@ void usage() {
" -v a, answer | Empty for a universal site answer or\n"
" | the most significant word(s) of the question.\n\n");
fprintf(stderr, " ENVIRONMENT\n\n"
" MP_USERNAME | The full name of the user.\n"
" MP_FULLNAME | The full name of the user.\n"
" MP_SITETYPE | The default password template.\n"
" MP_SITECOUNTER | The default counter value.\n\n");
exit(0);
@ -105,12 +105,12 @@ char *getlinep(const char *prompt) {
int main(int argc, char *const argv[]) {
// Read the environment.
char *userName = getenv( MP_env_username );
char *fullName = getenv( MP_env_fullname );
const char *masterPassword = NULL;
const char *siteName = NULL;
MPElementType siteType = MPElementTypeGeneratedLong;
MPSiteType siteType = MPSiteTypeGeneratedLong;
const char *siteTypeString = getenv( MP_env_sitetype );
MPElementVariant siteVariant = MPElementVariantPassword;
MPSiteVariant siteVariant = MPSiteVariantPassword;
const char *siteVariantString = NULL;
const char *siteContextString = NULL;
uint32_t siteCounter = 1;
@ -120,7 +120,7 @@ int main(int argc, char *const argv[]) {
for (int opt; (opt = getopt(argc, argv, "u:t:c:v:C:h")) != -1;)
switch (opt) {
case 'u':
userName = optarg;
fullName = optarg;
break;
case 't':
siteTypeString = optarg;
@ -140,7 +140,7 @@ int main(int argc, char *const argv[]) {
case '?':
switch (optopt) {
case 'u':
fprintf(stderr, "Missing user name to option: -%c\n", optopt);
fprintf(stderr, "Missing full name to option: -%c\n", optopt);
break;
case 't':
fprintf(stderr, "Missing type name to option: -%c\n", optopt);
@ -159,13 +159,13 @@ int main(int argc, char *const argv[]) {
siteName = argv[optind];
// Convert and validate input.
if (!userName) {
if (!(userName = getlinep("Your user name:"))) {
fprintf(stderr, "Missing user name.\n");
if (!fullName) {
if (!(fullName = getlinep("Your full name:"))) {
fprintf(stderr, "Missing full name.\n");
return 1;
}
}
trc("userName: %s\n", userName);
trc("fullName: %s\n", fullName);
if (!siteName) {
if (!(siteName = getlinep("Site name:"))) {
fprintf(stderr, "Missing site name.\n");
@ -180,10 +180,10 @@ int main(int argc, char *const argv[]) {
}
if (siteVariantString)
siteVariant = VariantWithName( siteVariantString );
if (siteVariant == MPElementVariantLogin)
siteType = MPElementTypeGeneratedName;
if (siteVariant == MPElementVariantAnswer)
siteType = MPElementTypeGeneratedPhrase;
if (siteVariant == MPSiteVariantLogin)
siteType = MPSiteTypeGeneratedName;
if (siteVariant == MPSiteVariantAnswer)
siteType = MPSiteTypeGeneratedPhrase;
if (siteTypeString)
siteType = TypeWithName( siteTypeString );
@ -202,7 +202,7 @@ int main(int argc, char *const argv[]) {
ssize_t linelen;
while ((linelen = getline(&line, &linecap, mpwConfig)) > 0) {
char *lineData = line;
if (strcmp(strsep(&lineData, ":"), userName) == 0) {
if (strcmp(strsep(&lineData, ":"), fullName) == 0) {
masterPassword = strcpy(malloc(strlen(lineData)), strsep(&lineData, "\n"));
break;
}
@ -214,7 +214,7 @@ int main(int argc, char *const argv[]) {
trc("masterPassword: %s\n", masterPassword);
// Summarize operation.
fprintf(stderr, "%s's password for %s:\n[ %s ]: ", userName, siteName, Identicon( userName, masterPassword ));
fprintf(stderr, "%s's password for %s:\n[ %s ]: ", fullName, siteName, Identicon( fullName, masterPassword ));
struct timeval startTime;
if (gettimeofday(&startTime, NULL) != 0) {
fprintf(stderr, "Could not get time: %d\n", errno);
@ -222,10 +222,10 @@ int main(int argc, char *const argv[]) {
}
// Calculate the master key salt.
const char *mpKeyScope = ScopeForVariant(MPElementVariantPassword);
const char *mpKeyScope = ScopeForVariant(MPSiteVariantPassword);
trc("key scope: %s\n", mpKeyScope);
const uint32_t n_userNameLength = htonl(strlen(userName));
const size_t masterKeySaltLength = strlen(mpKeyScope) + sizeof(n_userNameLength) + strlen(userName);
const uint32_t n_fullNameLength = htonl(strlen(fullName));
const size_t masterKeySaltLength = strlen(mpKeyScope) + sizeof(n_fullNameLength) + strlen(fullName);
char *masterKeySalt = (char *)malloc( masterKeySaltLength );
if (!masterKeySalt) {
fprintf(stderr, "Could not allocate master key salt: %d\n", errno);
@ -234,8 +234,8 @@ int main(int argc, char *const argv[]) {
char *mKS = masterKeySalt;
memcpy(mKS, mpKeyScope, strlen(mpKeyScope)); mKS += strlen(mpKeyScope);
memcpy(mKS, &n_userNameLength, sizeof(n_userNameLength)); mKS += sizeof(n_userNameLength);
memcpy(mKS, userName, strlen(userName)); mKS += strlen(userName);
memcpy(mKS, &n_fullNameLength, sizeof(n_fullNameLength)); mKS += sizeof(n_fullNameLength);
memcpy(mKS, fullName, strlen(fullName)); mKS += strlen(fullName);
if (mKS - masterKeySalt != masterKeySaltLength)
abort();
trc("masterKeySalt ID: %s\n", IDForBuf(masterKeySalt, masterKeySaltLength));

View File

@ -23,66 +23,66 @@
#include "types.h"
const MPElementType TypeWithName(const char *typeName) {
const MPSiteType TypeWithName(const char *typeName) {
char lowerTypeName[strlen(typeName)];
strcpy(lowerTypeName, typeName);
for (char *tN = lowerTypeName; *tN; ++tN)
*tN = tolower(*tN);
if (0 == strcmp(lowerTypeName, "x") || 0 == strcmp(lowerTypeName, "max") || 0 == strcmp(lowerTypeName, "maximum"))
return MPElementTypeGeneratedMaximum;
return MPSiteTypeGeneratedMaximum;
if (0 == strcmp(lowerTypeName, "l") || 0 == strcmp(lowerTypeName, "long"))
return MPElementTypeGeneratedLong;
return MPSiteTypeGeneratedLong;
if (0 == strcmp(lowerTypeName, "m") || 0 == strcmp(lowerTypeName, "med") || 0 == strcmp(lowerTypeName, "medium"))
return MPElementTypeGeneratedMedium;
return MPSiteTypeGeneratedMedium;
if (0 == strcmp(lowerTypeName, "b") || 0 == strcmp(lowerTypeName, "basic"))
return MPElementTypeGeneratedBasic;
return MPSiteTypeGeneratedBasic;
if (0 == strcmp(lowerTypeName, "s") || 0 == strcmp(lowerTypeName, "short"))
return MPElementTypeGeneratedShort;
return MPSiteTypeGeneratedShort;
if (0 == strcmp(lowerTypeName, "i") || 0 == strcmp(lowerTypeName, "pin"))
return MPElementTypeGeneratedPIN;
return MPSiteTypeGeneratedPIN;
if (0 == strcmp(lowerTypeName, "n") || 0 == strcmp(lowerTypeName, "name"))
return MPElementTypeGeneratedName;
return MPSiteTypeGeneratedName;
if (0 == strcmp(lowerTypeName, "p") || 0 == strcmp(lowerTypeName, "phrase"))
return MPElementTypeGeneratedPhrase;
return MPSiteTypeGeneratedPhrase;
fprintf(stderr, "Not a generated type name: %s", lowerTypeName);
abort();
}
const char *TemplateForType(MPElementType type, uint8_t seedByte) {
if (!(type & MPElementTypeClassGenerated)) {
const char *TemplateForType(MPSiteType type, uint8_t seedByte) {
if (!(type & MPSiteTypeClassGenerated)) {
fprintf(stderr, "Not a generated type: %d", type);
abort();
}
switch (type) {
case MPElementTypeGeneratedMaximum: {
case MPSiteTypeGeneratedMaximum: {
const char *templates[] = { "anoxxxxxxxxxxxxxxxxx", "axxxxxxxxxxxxxxxxxno" };
return templates[seedByte % 2];
}
case MPElementTypeGeneratedLong: {
case MPSiteTypeGeneratedLong: {
const char *templates[] = { "CvcvnoCvcvCvcv", "CvcvCvcvnoCvcv", "CvcvCvcvCvcvno", "CvccnoCvcvCvcv", "CvccCvcvnoCvcv", "CvccCvcvCvcvno", "CvcvnoCvccCvcv", "CvcvCvccnoCvcv", "CvcvCvccCvcvno", "CvcvnoCvcvCvcc", "CvcvCvcvnoCvcc", "CvcvCvcvCvccno", "CvccnoCvccCvcv", "CvccCvccnoCvcv", "CvccCvccCvcvno", "CvcvnoCvccCvcc", "CvcvCvccnoCvcc", "CvcvCvccCvccno", "CvccnoCvcvCvcc", "CvccCvcvnoCvcc", "CvccCvcvCvccno" };
return templates[seedByte % 21];
}
case MPElementTypeGeneratedMedium: {
case MPSiteTypeGeneratedMedium: {
const char *templates[] = { "CvcnoCvc", "CvcCvcno" };
return templates[seedByte % 2];
}
case MPElementTypeGeneratedBasic: {
case MPSiteTypeGeneratedBasic: {
const char *templates[] = { "aaanaaan", "aannaaan", "aaannaaa" };
return templates[seedByte % 3];
}
case MPElementTypeGeneratedShort: {
case MPSiteTypeGeneratedShort: {
return "Cvcn";
}
case MPElementTypeGeneratedPIN: {
case MPSiteTypeGeneratedPIN: {
return "nnnn";
}
case MPElementTypeGeneratedName: {
case MPSiteTypeGeneratedName: {
return "cvccvcvcv";
}
case MPElementTypeGeneratedPhrase: {
case MPSiteTypeGeneratedPhrase: {
const char *templates[] = { "cvcc cvc cvccvcv cvc", "cvc cvccvcvcv cvcv", "cv cvccv cvc cvcvccv" };
return templates[seedByte % 3];
}
@ -93,32 +93,32 @@ const char *TemplateForType(MPElementType type, uint8_t seedByte) {
}
}
const MPElementVariant VariantWithName(const char *variantName) {
const MPSiteVariant VariantWithName(const char *variantName) {
char lowerVariantName[strlen(variantName)];
strcpy(lowerVariantName, variantName);
for (char *vN = lowerVariantName; *vN; ++vN)
*vN = tolower(*vN);
if (0 == strcmp(lowerVariantName, "p") || 0 == strcmp(lowerVariantName, "password"))
return MPElementVariantPassword;
return MPSiteVariantPassword;
if (0 == strcmp(lowerVariantName, "l") || 0 == strcmp(lowerVariantName, "login"))
return MPElementVariantLogin;
return MPSiteVariantLogin;
if (0 == strcmp(lowerVariantName, "a") || 0 == strcmp(lowerVariantName, "answer"))
return MPElementVariantAnswer;
return MPSiteVariantAnswer;
fprintf(stderr, "Not a variant name: %s", lowerVariantName);
abort();
}
const char *ScopeForVariant(MPElementVariant variant) {
const char *ScopeForVariant(MPSiteVariant variant) {
switch (variant) {
case MPElementVariantPassword: {
case MPSiteVariantPassword: {
return "com.lyndir.masterpassword";
}
case MPElementVariantLogin: {
case MPSiteVariantLogin: {
return "com.lyndir.masterpassword.login";
}
case MPElementVariantAnswer: {
case MPSiteVariantAnswer: {
return "com.lyndir.masterpassword.answer";
}
default: {
@ -218,14 +218,14 @@ static int putvar(int c) {
}
#endif
const char *Identicon(const char *userName, const char *masterPassword) {
const char *Identicon(const char *fullName, const char *masterPassword) {
const char *leftArm[] = { "", "", "", "" };
const char *rightArm[] = { "", "", "", "" };
const char *body[] = { "", "", "", "", "", "" };
const char *accessory[] = { "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "", "" };
uint8_t identiconSeed[32];
HMAC_SHA256_Buf(masterPassword, strlen(masterPassword), userName, strlen(userName), identiconSeed);
HMAC_SHA256_Buf(masterPassword, strlen(masterPassword), fullName, strlen(fullName), identiconSeed);
uint8_t colorIdentifier = identiconSeed[4] % 7 + 1;
char *colorString, *resetString;

View File

@ -8,40 +8,40 @@
typedef enum {
/** Generate the password to log in with. */
MPElementVariantPassword,
MPSiteVariantPassword,
/** Generate the login name to log in as. */
MPElementVariantLogin,
MPSiteVariantLogin,
/** Generate the answer to a security question. */
MPElementVariantAnswer,
} MPElementVariant;
MPSiteVariantAnswer,
} MPSiteVariant;
typedef enum {
/** Generate the password. */
MPElementTypeClassGenerated = 1 << 4,
MPSiteTypeClassGenerated = 1 << 4,
/** Store the password. */
MPElementTypeClassStored = 1 << 5,
} MPElementTypeClass;
MPSiteTypeClassStored = 1 << 5,
} MPSiteTypeClass;
typedef enum {
/** Export the key-protected content data. */
MPElementFeatureExportContent = 1 << 10,
MPSiteFeatureExportContent = 1 << 10,
/** Never export content. */
MPElementFeatureDevicePrivate = 1 << 11,
} MPElementFeature;
MPSiteFeatureDevicePrivate = 1 << 11,
} MPSiteFeature;
typedef enum {
MPElementTypeGeneratedMaximum = 0x0 | MPElementTypeClassGenerated | 0x0,
MPElementTypeGeneratedLong = 0x1 | MPElementTypeClassGenerated | 0x0,
MPElementTypeGeneratedMedium = 0x2 | MPElementTypeClassGenerated | 0x0,
MPElementTypeGeneratedBasic = 0x4 | MPElementTypeClassGenerated | 0x0,
MPElementTypeGeneratedShort = 0x3 | MPElementTypeClassGenerated | 0x0,
MPElementTypeGeneratedPIN = 0x5 | MPElementTypeClassGenerated | 0x0,
MPElementTypeGeneratedName = 0xE | MPElementTypeClassGenerated | 0x0,
MPElementTypeGeneratedPhrase = 0xF | MPElementTypeClassGenerated | 0x0,
MPSiteTypeGeneratedMaximum = 0x0 | MPSiteTypeClassGenerated | 0x0,
MPSiteTypeGeneratedLong = 0x1 | MPSiteTypeClassGenerated | 0x0,
MPSiteTypeGeneratedMedium = 0x2 | MPSiteTypeClassGenerated | 0x0,
MPSiteTypeGeneratedBasic = 0x4 | MPSiteTypeClassGenerated | 0x0,
MPSiteTypeGeneratedShort = 0x3 | MPSiteTypeClassGenerated | 0x0,
MPSiteTypeGeneratedPIN = 0x5 | MPSiteTypeClassGenerated | 0x0,
MPSiteTypeGeneratedName = 0xE | MPSiteTypeClassGenerated | 0x0,
MPSiteTypeGeneratedPhrase = 0xF | MPSiteTypeClassGenerated | 0x0,
MPElementTypeStoredPersonal = 0x0 | MPElementTypeClassStored | MPElementFeatureExportContent,
MPElementTypeStoredDevicePrivate = 0x1 | MPElementTypeClassStored | MPElementFeatureDevicePrivate,
} MPElementType;
MPSiteTypeStoredPersonal = 0x0 | MPSiteTypeClassStored | MPSiteFeatureExportContent,
MPSiteTypeStoredDevicePrivate = 0x1 | MPSiteTypeClassStored | MPSiteFeatureDevicePrivate,
} MPSiteType;
#ifdef DEBUG
#define trc(...) fprintf(stderr, __VA_ARGS__)
@ -49,12 +49,12 @@ typedef enum {
#define trc(...) do {} while (0)
#endif
const MPElementVariant VariantWithName(const char *variantName);
const char *ScopeForVariant(MPElementVariant variant);
const MPElementType TypeWithName(const char *typeName);
const char *TemplateForType(MPElementType type, uint8_t seedByte);
const MPSiteVariant VariantWithName(const char *variantName);
const char *ScopeForVariant(MPSiteVariant variant);
const MPSiteType TypeWithName(const char *typeName);
const char *TemplateForType(MPSiteType type, uint8_t seedByte);
const char CharacterFromClass(char characterClass, uint8_t seedByte);
const char *IDForBuf(const void *buf, size_t length);
const char *Hex(const void *buf, size_t length);
const char *Identicon(const char *userName, const char *masterPassword);
const char *Identicon(const char *fullName, const char *masterPassword);

View File

@ -1,27 +0,0 @@
package com.lyndir.masterpassword;
import com.lyndir.masterpassword.entity.*;
/**
* <i>07 04, 2012</i>
*
* @author lhunath
*/
public enum MPElementTypeClass {
Generated(MPElementGeneratedEntity.class),
Stored(MPElementStoredEntity.class);
private final Class<? extends MPElementEntity> entityClass;
MPElementTypeClass(final Class<? extends MPElementEntity> entityClass) {
this.entityClass = entityClass;
}
public Class<? extends MPElementEntity> getEntityClass() {
return entityClass;
}
}

View File

@ -5,7 +5,7 @@ package com.lyndir.masterpassword;
*
* @author lhunath
*/
public enum MPElementFeature {
public enum MPSiteFeature {
/** Export the key-protected content data. */
ExportContent,

View File

@ -5,7 +5,6 @@ import com.google.common.collect.ImmutableSet;
import com.lyndir.lhunath.opal.system.logging.Logger;
import java.util.List;
import java.util.Set;
import javax.annotation.Generated;
/**
@ -13,14 +12,14 @@ import javax.annotation.Generated;
*
* @author lhunath
*/
public enum MPElementType {
public enum MPSiteType {
GeneratedMaximum( "20 characters, contains symbols.", //
ImmutableList.of( "x", "max", "maximum" ), MPElementTypeClass.Generated, //
ImmutableList.of( "x", "max", "maximum" ), MPSiteTypeClass.Generated, //
ImmutableList.of( new MPTemplate( "anoxxxxxxxxxxxxxxxxx" ), new MPTemplate( "axxxxxxxxxxxxxxxxxno" ) ) ),
GeneratedLong( "Copy-friendly, 14 characters, contains symbols.", //
ImmutableList.of( "l", "long" ), MPElementTypeClass.Generated, //
ImmutableList.of( "l", "long" ), MPSiteTypeClass.Generated, //
ImmutableList.of( new MPTemplate( "CvcvnoCvcvCvcv" ), new MPTemplate( "CvcvCvcvnoCvcv" ),
new MPTemplate( "CvcvCvcvCvcvno" ), new MPTemplate( "CvccnoCvcvCvcv" ),
new MPTemplate( "CvccCvcvnoCvcv" ), new MPTemplate( "CvccCvcvCvcvno" ),
@ -34,56 +33,56 @@ public enum MPElementType {
new MPTemplate( "CvccCvcvCvccno" ) ) ),
GeneratedMedium( "Copy-friendly, 8 characters, contains symbols.", //
ImmutableList.of( "m", "med", "medium" ), MPElementTypeClass.Generated, //
ImmutableList.of( "m", "med", "medium" ), MPSiteTypeClass.Generated, //
ImmutableList.of( new MPTemplate( "CvcnoCvc" ), new MPTemplate( "CvcCvcno" ) ) ),
GeneratedBasic( "8 characters, no symbols.", //
ImmutableList.of( "b", "basic" ), MPElementTypeClass.Generated, //
ImmutableList.of( "b", "basic" ), MPSiteTypeClass.Generated, //
ImmutableList.of( new MPTemplate( "aaanaaan" ), new MPTemplate( "aannaaan" ), new MPTemplate( "aaannaaa" ) ) ),
GeneratedShort( "Copy-friendly, 4 characters, no symbols.", //
ImmutableList.of( "s", "short" ), MPElementTypeClass.Generated, //
ImmutableList.of( "s", "short" ), MPSiteTypeClass.Generated, //
ImmutableList.of( new MPTemplate( "Cvcn" ) ) ),
GeneratedPIN( "4 numbers.", //
ImmutableList.of( "i", "pin" ), MPElementTypeClass.Generated, //
ImmutableList.of( "i", "pin" ), MPSiteTypeClass.Generated, //
ImmutableList.of( new MPTemplate( "nnnn" ) ) ),
GeneratedName( "9 letter name.", //
ImmutableList.of( "n", "name" ), MPElementTypeClass.Generated, //
ImmutableList.of( "n", "name" ), MPSiteTypeClass.Generated, //
ImmutableList.of( new MPTemplate( "cvccvcvcv" ) ) ),
GeneratedPhrase( "20 character sentence.", //
ImmutableList.of( "p", "phrase" ), MPElementTypeClass.Generated, //
ImmutableList.of( "p", "phrase" ), MPSiteTypeClass.Generated, //
ImmutableList.of( new MPTemplate( "cvcc cvc cvccvcv cvc" ), new MPTemplate( "cvc cvccvcvcv cvcv" ),
new MPTemplate( "cv cvccv cvc cvcvccv" ) ) ),
StoredPersonal( "AES-encrypted, exportable.", //
ImmutableList.of( "personal" ), MPElementTypeClass.Stored, //
ImmutableList.<MPTemplate>of(), MPElementFeature.ExportContent ),
ImmutableList.of( "personal" ), MPSiteTypeClass.Stored, //
ImmutableList.<MPTemplate>of(), MPSiteFeature.ExportContent ),
StoredDevicePrivate( "AES-encrypted, not exported.", //
ImmutableList.of( "device" ), MPElementTypeClass.Stored, //
ImmutableList.<MPTemplate>of(), MPElementFeature.DevicePrivate );
ImmutableList.of( "device" ), MPSiteTypeClass.Stored, //
ImmutableList.<MPTemplate>of(), MPSiteFeature.DevicePrivate );
static final Logger logger = Logger.get( MPElementType.class );
static final Logger logger = Logger.get( MPSiteType.class );
private final String description;
private final List<String> options;
private final MPElementTypeClass typeClass;
private final List<MPTemplate> templates;
private final Set<MPElementFeature> typeFeatures;
private final String description;
private final List<String> options;
private final MPSiteTypeClass typeClass;
private final List<MPTemplate> templates;
private final Set<MPSiteFeature> typeFeatures;
MPElementType(final String description, final List<String> options, final MPElementTypeClass typeClass,
final List<MPTemplate> templates, final MPElementFeature... typeFeatures) {
MPSiteType(final String description, final List<String> options, final MPSiteTypeClass typeClass, final List<MPTemplate> templates,
final MPSiteFeature... typeFeatures) {
this.description = description;
this.options = options;
this.typeClass = typeClass;
this.templates = templates;
ImmutableSet.Builder<MPElementFeature> typeFeaturesBuilder = ImmutableSet.builder();
for (final MPElementFeature typeFeature : typeFeatures) {
ImmutableSet.Builder<MPSiteFeature> typeFeaturesBuilder = ImmutableSet.builder();
for (final MPSiteFeature typeFeature : typeFeatures) {
typeFeaturesBuilder.add( typeFeature );
}
this.typeFeatures = typeFeaturesBuilder.build();
@ -98,12 +97,12 @@ public enum MPElementType {
return options;
}
public MPElementTypeClass getTypeClass() {
public MPSiteTypeClass getTypeClass() {
return typeClass;
}
public Set<MPElementFeature> getTypeFeatures() {
public Set<MPSiteFeature> getTypeFeatures() {
return typeFeatures;
}
@ -113,9 +112,9 @@ public enum MPElementType {
*
* @return The type registered for the given option.
*/
public static MPElementType forOption(final String option) {
public static MPSiteType forOption(final String option) {
for (final MPElementType type : values())
for (final MPSiteType type : values())
if (type.getOptions().contains( option.toLowerCase() ))
return type;
@ -127,12 +126,12 @@ public enum MPElementType {
*
* @return The type registered with the given name.
*/
public static MPElementType forName(final String name) {
public static MPSiteType forName(final String name) {
if (name == null)
return null;
for (final MPElementType type : values())
for (final MPSiteType type : values())
if (type.name().equalsIgnoreCase( name ))
return type;
@ -144,10 +143,10 @@ public enum MPElementType {
*
* @return All types that support the given class.
*/
public static ImmutableList<MPElementType> forClass(final MPElementTypeClass typeClass) {
public static ImmutableList<MPSiteType> forClass(final MPSiteTypeClass typeClass) {
ImmutableList.Builder<MPElementType> types = ImmutableList.builder();
for (final MPElementType type : values())
ImmutableList.Builder<MPSiteType> types = ImmutableList.builder();
for (final MPSiteType type : values())
if (type.getTypeClass() == typeClass)
types.add( type );

View File

@ -0,0 +1,11 @@
package com.lyndir.masterpassword;
/**
* <i>07 04, 2012</i>
*
* @author lhunath
*/
public enum MPSiteTypeClass {
Generated,
Stored
}

View File

@ -8,7 +8,7 @@ import java.util.List;
/**
* @author lhunath, 14-12-02
*/
public enum MPElementVariant {
public enum MPSiteVariant {
Password( "The password to log in with.", "Doesn't currently use a context.", //
ImmutableList.of( "p", "password" ), "com.lyndir.masterpassword" ),
Login( "The username to log in as.", "Doesn't currently use a context.", //
@ -16,14 +16,14 @@ public enum MPElementVariant {
Answer( "The answer to a security question.", "Empty for a universal site answer or\nthe most significant word(s) of the question.", //
ImmutableList.of( "a", "answer" ), "com.lyndir.masterpassword.answer" );
static final Logger logger = Logger.get( MPElementType.class );
static final Logger logger = Logger.get( MPSiteType.class );
private final String description;
private final String contextDescription;
private final List<String> options;
private final String scope;
MPElementVariant(final String description, final String contextDescription, final List<String> options, final String scope) {
MPSiteVariant(final String description, final String contextDescription, final List<String> options, final String scope) {
this.contextDescription = contextDescription;
this.options = options;
@ -52,9 +52,9 @@ public enum MPElementVariant {
*
* @return The variant registered for the given option.
*/
public static MPElementVariant forOption(final String option) {
public static MPSiteVariant forOption(final String option) {
for (final MPElementVariant variant : values())
for (final MPSiteVariant variant : values())
if (variant.getOptions().contains( option.toLowerCase() ))
return variant;
@ -65,12 +65,12 @@ public enum MPElementVariant {
*
* @return The variant registered with the given name.
*/
public static MPElementVariant forName(final String name) {
public static MPSiteVariant forName(final String name) {
if (name == null)
return null;
for (final MPElementVariant type : values())
for (final MPSiteVariant type : values())
if (type.name().equalsIgnoreCase( name ))
return type;

View File

@ -4,7 +4,6 @@ import com.google.common.base.Charsets;
import com.google.common.base.Preconditions;
import com.google.common.primitives.Bytes;
import com.lambdaworks.crypto.SCrypt;
import com.lyndir.lhunath.opal.crypto.CryptUtils;
import com.lyndir.lhunath.opal.system.*;
import com.lyndir.lhunath.opal.system.logging.Logger;
import java.nio.ByteBuffer;
@ -32,22 +31,22 @@ public class MasterKey {
private static final MessageDigests MP_hash = MessageDigests.SHA256;
private static final MessageAuthenticationDigests MP_mac = MessageAuthenticationDigests.HmacSHA256;
private final String userName;
private final String fullName;
private final byte[] masterKey;
private boolean valid;
public MasterKey(final String userName, final String masterPassword) {
public MasterKey(final String fullName, final String masterPassword) {
this.userName = userName;
logger.trc( "userName: %s", userName );
this.fullName = fullName;
logger.trc( "fullName: %s", fullName );
logger.trc( "masterPassword: %s", masterPassword );
long start = System.currentTimeMillis();
byte[] userNameBytes = userName.getBytes( MP_charset );
byte[] userNameBytes = fullName.getBytes( MP_charset );
byte[] userNameLengthBytes = bytesForInt( userNameBytes.length );
String mpKeyScope = MPElementVariant.Password.getScope();
String mpKeyScope = MPSiteVariant.Password.getScope();
byte[] masterKeySalt = Bytes.concat( mpKeyScope.getBytes( MP_charset ), userNameLengthBytes, userNameBytes );
logger.trc( "key scope: %s", mpKeyScope );
logger.trc( "masterKeySalt ID: %s", idForBytes( masterKeySalt ) );
@ -63,9 +62,9 @@ public class MasterKey {
}
}
public String getUserName() {
public String getFullName() {
return userName;
return fullName;
}
public String getKeyID() {
@ -74,7 +73,7 @@ public class MasterKey {
return idForBytes( masterKey );
}
private byte[] getSubkey(final int subkeyLength) {
private byte[] getSubKey(final int subkeyLength) {
Preconditions.checkState( valid );
byte[] subkey = new byte[Math.min( subkeyLength, masterKey.length )];
@ -83,10 +82,10 @@ public class MasterKey {
return subkey;
}
public String encode(final String siteName, final MPElementType siteType, int siteCounter, final MPElementVariant siteVariant,
public String encode(final String siteName, final MPSiteType siteType, int siteCounter, final MPSiteVariant siteVariant,
@Nullable final String siteContext) {
Preconditions.checkState( valid );
Preconditions.checkArgument( siteType.getTypeClass() == MPElementTypeClass.Generated );
Preconditions.checkArgument( siteType.getTypeClass() == MPSiteTypeClass.Generated );
Preconditions.checkArgument( !siteName.isEmpty() );
logger.trc( "siteName: %s", siteName );

View File

@ -1,10 +0,0 @@
package com.lyndir.masterpassword.entity;
/**
* <i>07 04, 2012</i>
*
* @author lhunath
*/
public class MPElementEntity {
}

View File

@ -1,10 +0,0 @@
package com.lyndir.masterpassword.entity;
/**
* <i>07 04, 2012</i>
*
* @author lhunath
*/
public class MPElementGeneratedEntity extends MPElementEntity {
}

View File

@ -1,10 +0,0 @@
package com.lyndir.masterpassword.entity;
/**
* <i>07 04, 2012</i>
*
* @author lhunath
*/
public class MPElementStoredEntity extends MPElementEntity {
}

View File

@ -2,9 +2,7 @@ package com.lyndir.masterpassword;
import static com.lyndir.lhunath.opal.system.util.ObjectUtils.*;
import com.google.common.base.Verify;
import com.lyndir.lhunath.opal.system.logging.Logger;
import com.lyndir.lhunath.opal.system.util.NFunctionNN;
import com.lyndir.lhunath.opal.system.util.NNSupplier;
import java.util.List;
import javax.annotation.Nonnull;
@ -165,12 +163,12 @@ public class MPWTests {
return siteCounter;
}
public MPElementType getSiteType() {
return MPElementType.forName( siteType );
public MPSiteType getSiteType() {
return MPSiteType.forName( siteType );
}
public MPElementVariant getSiteVariant() {
return MPElementVariant.forName( siteVariant );
public MPSiteVariant getSiteVariant() {
return MPSiteVariant.forName( siteVariant );
}
public String getSiteContext() {

View File

@ -6,7 +6,6 @@ import com.google.common.io.Resources;
import com.lyndir.lhunath.opal.system.logging.Logger;
import java.net.URL;
import javax.xml.bind.JAXBContext;
import javax.xml.bind.Unmarshaller;
import org.testng.annotations.BeforeMethod;
import org.testng.annotations.Test;
@ -46,7 +45,7 @@ public class MasterKeyTest {
public void testGetUserName()
throws Exception {
assertEquals( new MasterKey( defaultCase.getFullName(), defaultCase.getMasterPassword() ).getUserName(),
assertEquals( new MasterKey( defaultCase.getFullName(), defaultCase.getMasterPassword() ).getFullName(),
defaultCase.getFullName() );
}

View File

@ -87,8 +87,8 @@ public class EmergencyActivity extends Activity {
sitePasswordField.setPaintFlags( userNameField.getPaintFlags() | Paint.SUBPIXEL_TEXT_FLAG );
typeField.setAdapter(
new ArrayAdapter<MPElementType>( this, R.layout.type_item, MPElementType.forClass( MPElementTypeClass.Generated ) ) );
typeField.setSelection( MPElementType.GeneratedLong.ordinal() );
new ArrayAdapter<MPSiteType>( this, R.layout.type_item, MPSiteType.forClass( MPSiteTypeClass.Generated ) ) );
typeField.setSelection( MPSiteType.GeneratedLong.ordinal() );
counterField.setMinValue( 1 );
counterField.setMaxValue( Integer.MAX_VALUE );
@ -170,7 +170,7 @@ public class EmergencyActivity extends Activity {
private void updateSitePassword() {
final String siteName = siteNameField.getText().toString();
final MPElementType type = (MPElementType) typeField.getSelectedItem();
final MPSiteType type = (MPSiteType) typeField.getSelectedItem();
final int counter = counterField.getValue();
if (masterKeyFuture == null || siteName.isEmpty() || type == null) {

View File

@ -48,8 +48,8 @@ public class CLI {
String siteName = null, masterPassword, context = null;
String userName = System.getenv( ENV_USERNAME );
String siteTypeName = ifNotNullElse( System.getenv( ENV_SITETYPE ), "" );
MPElementType siteType = siteTypeName.isEmpty()? MPElementType.GeneratedLong: MPElementType.forOption( siteTypeName );
MPElementVariant variant = MPElementVariant.Password;
MPSiteType siteType = siteTypeName.isEmpty()? MPSiteType.GeneratedLong: MPSiteType.forOption( siteTypeName );
MPSiteVariant variant = MPSiteVariant.Password;
String siteCounterName = ifNotNullElse( System.getenv( ENV_SITECOUNTER ), "" );
int siteCounter = siteCounterName.isEmpty()? 1: Integer.parseInt( siteCounterName );
@ -68,7 +68,7 @@ public class CLI {
else if ("-t".equals( arg ) || "--type".equals( arg ))
typeArg = true;
else if (typeArg) {
siteType = MPElementType.forOption( arg );
siteType = MPSiteType.forOption( arg );
typeArg = false;
}
@ -84,7 +84,7 @@ public class CLI {
else if ("-v".equals( arg ) || "--variant".equals( arg ))
variantArg = true;
else if (variantArg) {
variant = MPElementVariant.forOption( arg );
variant = MPSiteVariant.forOption( arg );
variantArg = false;
}
@ -106,13 +106,13 @@ public class CLI {
System.out.format( " Defaults to %s in env or 'long' for password, 'name' for login.\n", ENV_SITETYPE );
int optionsLength = 0;
Map<String, MPElementType> typeMap = Maps.newLinkedHashMap();
for (MPElementType elementType : MPElementType.values()) {
Map<String, MPSiteType> typeMap = Maps.newLinkedHashMap();
for (MPSiteType elementType : MPSiteType.values()) {
String options = Joiner.on( ", " ).join( elementType.getOptions() );
typeMap.put( options, elementType );
optionsLength = Math.max( optionsLength, options.length() );
}
for (Map.Entry<String, MPElementType> entry : typeMap.entrySet()) {
for (Map.Entry<String, MPSiteType> entry : typeMap.entrySet()) {
String infoString = strf( " -v %" + optionsLength + "s | ", entry.getKey() );
String infoNewline = "\n" + StringUtils.repeat( " ", infoString.length() - 3 ) + " | ";
infoString += entry.getValue().getDescription().replaceAll( "\n", infoNewline );
@ -126,13 +126,13 @@ public class CLI {
System.out.format( " Defaults to 'password'.\n" );
optionsLength = 0;
Map<String, MPElementVariant> variantMap = Maps.newLinkedHashMap();
for (MPElementVariant elementVariant : MPElementVariant.values()) {
Map<String, MPSiteVariant> variantMap = Maps.newLinkedHashMap();
for (MPSiteVariant elementVariant : MPSiteVariant.values()) {
String options = Joiner.on( ", " ).join( elementVariant.getOptions() );
variantMap.put( options, elementVariant );
optionsLength = Math.max( optionsLength, options.length() );
}
for (Map.Entry<String, MPElementVariant> entry : variantMap.entrySet()) {
for (Map.Entry<String, MPSiteVariant> entry : variantMap.entrySet()) {
String infoString = strf( " -v %" + optionsLength + "s | ", entry.getKey() );
String infoNewline = "\n" + StringUtils.repeat( " ", infoString.length() - 3 ) + " | ";
infoString += entry.getValue().getDescription().replaceAll( "\n", infoNewline );
@ -142,7 +142,7 @@ public class CLI {
System.out.format( " -C context A variant-specific context.\n" );
System.out.format( " Defaults to empty.\n" );
for (Map.Entry<String, MPElementVariant> entry : variantMap.entrySet()) {
for (Map.Entry<String, MPSiteVariant> entry : variantMap.entrySet()) {
String infoString = strf( " -v %" + optionsLength + "s | ", entry.getKey() );
String infoNewline = "\n" + StringUtils.repeat( " ", infoString.length() - 3 ) + " | ";
infoString += entry.getValue().getContextDescription().replaceAll( "\n", infoNewline );

View File

@ -17,12 +17,12 @@ import javax.swing.event.*;
*/
public class PasswordFrame extends JFrame implements DocumentListener {
private final User user;
private final JTextField siteNameField;
private final JComboBox<MPElementType> siteTypeField;
private final JSpinner siteCounterField;
private final JTextField passwordField;
private final JLabel tipLabel;
private final User user;
private final JTextField siteNameField;
private final JComboBox<MPSiteType> siteTypeField;
private final JSpinner siteCounterField;
private final JTextField passwordField;
private final JLabel tipLabel;
public PasswordFrame(User user)
throws HeadlessException {
@ -89,7 +89,7 @@ public class PasswordFrame extends JFrame implements DocumentListener {
} );
// Site Type & Counter
MPElementType[] types = Iterables.toArray( MPElementType.forClass( MPElementTypeClass.Generated ), MPElementType.class );
MPSiteType[] types = Iterables.toArray( MPSiteType.forClass( MPSiteTypeClass.Generated ), MPSiteType.class );
JComponent siteSettings = Components.boxLayout( BoxLayout.LINE_AXIS, //
siteTypeField = new JComboBox<>( types ), //
siteCounterField = new JSpinner(
@ -104,7 +104,7 @@ public class PasswordFrame extends JFrame implements DocumentListener {
siteTypeField.setFont( Res.exoRegular().deriveFont( 12f ) );
siteTypeField.setAlignmentX( LEFT_ALIGNMENT );
siteTypeField.setAlignmentY( CENTER_ALIGNMENT );
siteTypeField.setSelectedItem( MPElementType.GeneratedLong );
siteTypeField.setSelectedItem( MPSiteType.GeneratedLong );
siteTypeField.addItemListener( new ItemListener() {
@Override
public void itemStateChanged(final ItemEvent e) {
@ -146,11 +146,11 @@ public class PasswordFrame extends JFrame implements DocumentListener {
}
private void updatePassword(final PasswordCallback callback) {
final MPElementType siteType = (MPElementType) siteTypeField.getSelectedItem();
final MPSiteType siteType = (MPSiteType) siteTypeField.getSelectedItem();
final String siteName = siteNameField.getText();
final int siteCounter = (Integer) siteCounterField.getValue();
if (siteType.getTypeClass() != MPElementTypeClass.Generated || siteName == null || siteName.isEmpty() || !user.hasKey()) {
if (siteType.getTypeClass() != MPSiteTypeClass.Generated || siteName == null || siteName.isEmpty() || !user.hasKey()) {
passwordField.setText( null );
tipLabel.setText( null );
return;
@ -159,7 +159,7 @@ public class PasswordFrame extends JFrame implements DocumentListener {
Res.execute( new Runnable() {
@Override
public void run() {
final String sitePassword = user.getKey().encode( siteName, siteType, siteCounter, MPElementVariant.Password, null );
final String sitePassword = user.getKey().encode( siteName, siteType, siteCounter, MPSiteVariant.Password, null );
if (callback != null)
callback.passwordGenerated( siteName, sitePassword );