2
0

WIP - Initial complete C implementation that's still buggy and generates broken passwords, yay.

This commit is contained in:
Maarten Billemont 2014-06-07 01:27:18 -04:00
parent c4dca14800
commit 2bc357cee6
4 changed files with 143 additions and 66 deletions

View File

@ -1,3 +1,5 @@
#!/usr/bin/env bash -e #!/usr/bin/env bash -e
gcc types.c -o types.o # Run with -DDEBUG to enable trace-level output.
gcc -I"lib/scrypt/lib" -I"lib/scrypt/libcperciva" -l "crypto_aesctr.o" -l "sha256.o" -l "crypto_scrypt-nosse.o" -l "memlimit.o" -l "scryptenc_cpuperf.o" -l"scryptenc.o" -l"types.o" -l"crypto" -L"lib/scrypt" mpw.c -o mpw
gcc -c types.c -o types.o "$@"
gcc -I"lib/scrypt/lib" -I"lib/scrypt/libcperciva" -l "crypto_aesctr.o" -l "sha256.o" -l "crypto_scrypt-nosse.o" -l "memlimit.o" -l "scryptenc_cpuperf.o" -l"scryptenc.o" -l"types.o" -l"crypto" -L"." -L"lib/scrypt" mpw.c -o mpw "$@"

View File

@ -63,6 +63,7 @@ int main(int argc, char *const argv[]) {
const char *userName = getenv( MP_env_username ); const char *userName = getenv( MP_env_username );
const char *masterPassword = NULL; const char *masterPassword = NULL;
const char *siteName = NULL; const char *siteName = NULL;
MPElementType siteType = MPElementTypeGeneratedLong;
const char *siteTypeString = getenv( MP_env_sitetype ); const char *siteTypeString = getenv( MP_env_sitetype );
uint32_t siteCounter = 1; uint32_t siteCounter = 1;
const char *siteCounterString = getenv( MP_env_sitecounter ); const char *siteCounterString = getenv( MP_env_sitecounter );
@ -106,16 +107,22 @@ int main(int argc, char *const argv[]) {
fprintf(stderr, "Missing user name.\n"); fprintf(stderr, "Missing user name.\n");
return 1; return 1;
} }
trc("userName: %s\n", userName);
if (!siteName) { if (!siteName) {
fprintf(stderr, "Missing site name.\n"); fprintf(stderr, "Missing site name.\n");
return 1; return 1;
} }
trc("siteName: %s\n", siteName);
if (siteCounterString) if (siteCounterString)
siteCounter = atoi( siteCounterString ); siteCounter = atoi( siteCounterString );
if (siteCounter < 1) { if (siteCounter < 1) {
fprintf(stderr, "Invalid site counter: %d\n", siteCounter); fprintf(stderr, "Invalid site counter: %d\n", siteCounter);
return 1; return 1;
} }
trc("siteCounter: %d\n", siteCounter);
if (siteTypeString)
siteType = TypeWithName( siteTypeString );
trc("siteType: %d (%s)\n", siteType, siteTypeString);
// Read the master password. // Read the master password.
char *mpwConfigPath = homedir(".mpw"); char *mpwConfigPath = homedir(".mpw");
@ -123,6 +130,7 @@ int main(int argc, char *const argv[]) {
fprintf(stderr, "Couldn't resolve path for configuration file: %d\n", errno); fprintf(stderr, "Couldn't resolve path for configuration file: %d\n", errno);
return 1; return 1;
} }
trc("mpwConfigPath: %s\n", mpwConfigPath);
FILE *mpwConfig = fopen(mpwConfigPath, "r"); FILE *mpwConfig = fopen(mpwConfigPath, "r");
if (!mpwConfig) { if (!mpwConfig) {
fprintf(stderr, "Couldn't open configuration file: %s: %d\n", mpwConfigPath, errno); fprintf(stderr, "Couldn't open configuration file: %s: %d\n", mpwConfigPath, errno);
@ -141,6 +149,7 @@ int main(int argc, char *const argv[]) {
fprintf(stderr, "Missing master password for user: %s\n", userName); fprintf(stderr, "Missing master password for user: %s\n", userName);
return 1; return 1;
} }
trc("masterPassword: %s\n", masterPassword);
// Calculate the master key. // Calculate the master key.
uint8_t *masterKey = malloc( MP_dkLen ); uint8_t *masterKey = malloc( MP_dkLen );
@ -178,15 +187,16 @@ int main(int argc, char *const argv[]) {
free(sitePasswordInfo); free(sitePasswordInfo);
// Determine the cipher. // Determine the cipher.
const char *cipher = CipherForType(siteType, sitePasswordSeed); const char *cipher = CipherForType(siteType, sitePasswordSeed[0]);
//trc(@"type %@, ciphers: %@, selected: %@", [self nameOfType:type], typeCiphers, cipher); trc("type %s, cipher: %s\n", siteTypeString, cipher);
// Encode the password from the seed using the cipher. // Encode the password from the seed using the cipher.
//NSAssert([seed length] >= [cipher length] + 1, @"Insufficient seed bytes to encode cipher."); //NSAssert([seed length] >= [cipher length] + 1, @"Insufficient seed bytes to encode cipher.");
char *sitePassword = calloc(strlen(cipher) + 1, sizeof(char)); char *sitePassword = calloc(strlen(cipher) + 1, sizeof(char));
for (int c = 0; c < strlen(cipher); ++c) for (int c = 0; c < strlen(cipher); ++c) {
//trc(@"class %@ has characters: %@, index: %u, selected: %@", cipherClass, cipherClassCharacters, keyByte, character);
sitePassword[c] = CharacterFromClass(cipher[c], sitePasswordSeed[c + 1]); sitePassword[c] = CharacterFromClass(cipher[c], sitePasswordSeed[c + 1]);
trc("class %c, character: %c\n", cipher[c], sitePassword[c]);
}
memset(sitePasswordSeed, 0, sizeof(sitePasswordSeed)); memset(sitePasswordSeed, 0, sizeof(sitePasswordSeed));
// Output the password. // Output the password.

View File

@ -6,58 +6,116 @@
// Copyright (c) 2012 Lyndir. All rights reserved. // Copyright (c) 2012 Lyndir. All rights reserved.
// //
#include <stdlib.h>
#include <stdio.h> #include <stdio.h>
#include <string.h>
#include <ctype.h>
#include "types.h" #include "types.h"
const char *CipherForType(MPElementType type, char seedByte) { const MPElementType 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;
if (0 == strcmp(lowerTypeName, "l") || 0 == strcmp(lowerTypeName, "long"))
return MPElementTypeGeneratedLong;
if (0 == strcmp(lowerTypeName, "m") || 0 == strcmp(lowerTypeName, "med") || 0 == strcmp(lowerTypeName, "medium"))
return MPElementTypeGeneratedMedium;
if (0 == strcmp(lowerTypeName, "b") || 0 == strcmp(lowerTypeName, "basic"))
return MPElementTypeGeneratedBasic;
if (0 == strcmp(lowerTypeName, "s") || 0 == strcmp(lowerTypeName, "short"))
return MPElementTypeGeneratedShort;
if (0 == strcmp(lowerTypeName, "p") || 0 == strcmp(lowerTypeName, "pin"))
return MPElementTypeGeneratedPIN;
fprintf(stderr, "Not a generated type name: %s", lowerTypeName);
abort();
}
const char *CipherForType(MPElementType type, uint8_t seedByte) {
if (!(type & MPElementTypeClassGenerated)) { if (!(type & MPElementTypeClassGenerated)) {
fprintf(stderr, "Not a generated type: %d", type); fprintf(stderr, "Not a generated type: %d", type);
abort(); abort();
} }
switch (type) { switch (type) {
case MPElementTypeGeneratedMaximum: case MPElementTypeGeneratedMaximum: {
char *ciphers = { "anoxxxxxxxxxxxxxxxxx", "axxxxxxxxxxxxxxxxxno" }; char *ciphers[] = { "anoxxxxxxxxxxxxxxxxx", "axxxxxxxxxxxxxxxxxno" };
return ciphers[seedByte % 2]; return ciphers[seedByte % 2];
case MPElementTypeGeneratedLong: }
char *ciphers = { "CvcvnoCvcvCvcv", "CvcvCvcvnoCvcv", "CvcvCvcvCvcvno", "CvccnoCvcvCvcv", "CvccCvcvnoCvcv", "CvccCvcvCvcvno", "CvcvnoCvccCvcv", "CvcvCvccnoCvcv", "CvcvCvccCvcvno", "CvcvnoCvcvCvcc", "CvcvCvcvnoCvcc", "CvcvCvcvCvccno", "CvccnoCvccCvcv", "CvccCvccnoCvcv", "CvccCvccCvcvno", "CvcvnoCvccCvcc", "CvcvCvccnoCvcc", "CvcvCvccCvccno", "CvccnoCvcvCvcc", "CvccCvcvnoCvcc", "CvccCvcvCvccno" }; case MPElementTypeGeneratedLong: {
char *ciphers[] = { "CvcvnoCvcvCvcv", "CvcvCvcvnoCvcv", "CvcvCvcvCvcvno", "CvccnoCvcvCvcv", "CvccCvcvnoCvcv", "CvccCvcvCvcvno", "CvcvnoCvccCvcv", "CvcvCvccnoCvcv", "CvcvCvccCvcvno", "CvcvnoCvcvCvcc", "CvcvCvcvnoCvcc", "CvcvCvcvCvccno", "CvccnoCvccCvcv", "CvccCvccnoCvcv", "CvccCvccCvcvno", "CvcvnoCvccCvcc", "CvcvCvccnoCvcc", "CvcvCvccCvccno", "CvccnoCvcvCvcc", "CvccCvcvnoCvcc", "CvccCvcvCvccno" };
return ciphers[seedByte % 21]; return ciphers[seedByte % 21];
case MPElementTypeGeneratedMedium: }
char *ciphers = { "CvcnoCvc", "CvcCvcno" }; case MPElementTypeGeneratedMedium: {
char *ciphers[] = { "CvcnoCvc", "CvcCvcno" };
return ciphers[seedByte % 2]; return ciphers[seedByte % 2];
case MPElementTypeGeneratedBasic: }
char *ciphers = { "aaanaaan", "aannaaan", "aaannaaa" }; case MPElementTypeGeneratedBasic: {
char *ciphers[] = { "aaanaaan", "aannaaan", "aaannaaa" };
return ciphers[seedByte % 3]; return ciphers[seedByte % 3];
case MPElementTypeGeneratedShort: }
case MPElementTypeGeneratedShort: {
return "Cvcn"; return "Cvcn";
case MPElementTypeGeneratedPIN: }
case MPElementTypeGeneratedPIN: {
return "nnnn"; return "nnnn";
} }
default: {
fprintf(stderr, "Unknown generated type: %d", type);
abort();
}
}
} }
const char CharacterFromClass(char characterClass, char seedByte) { const char CharacterFromClass(char characterClass, uint8_t seedByte) {
const char *classCharacters;
switch (characterClass) { switch (characterClass) {
case 'V': case 'V': {
return "AEIOU"[seedByte]; classCharacters = "AEIOU";
case 'C': break;
return "BCDFGHJKLMNPQRSTVWXYZ"[seedByte];
case 'v':
return "aeiou"[seedByte];
case 'c':
return "bcdfghjklmnpqrstvwxyz"[seedByte];
case 'A':
return "AEIOUBCDFGHJKLMNPQRSTVWXYZ"[seedByte];
case 'a':
return "AEIOUaeiouBCDFGHJKLMNPQRSTVWXYZbcdfghjklmnpqrstvwxyz"[seedByte];
case 'n':
return "0123456789"[seedByte];
case 'o':
return "@&amp;%?,=[]_:-+*$#!'^~;()/."[seedByte];
case 'x':
return "AEIOUaeiouBCDFGHJKLMNPQRSTVWXYZbcdfghjklmnpqrstvwxyz0123456789!@#$%^&amp;*()"[seedByte];
} }
case 'C': {
classCharacters = "BCDFGHJKLMNPQRSTVWXYZ";
break;
}
case 'v': {
classCharacters = "aeiou";
break;
}
case 'c': {
classCharacters = "bcdfghjklmnpqrstvwxyz";
break;
}
case 'A': {
classCharacters = "AEIOUBCDFGHJKLMNPQRSTVWXYZ";
break;
}
case 'a': {
classCharacters = "AEIOUaeiouBCDFGHJKLMNPQRSTVWXYZbcdfghjklmnpqrstvwxyz";
break;
}
case 'n': {
classCharacters = "0123456789";
break;
}
case 'o': {
classCharacters = "@&%?,=[]_:-+*$#!'^~;()/.";
break;
}
case 'x': {
classCharacters = "AEIOUaeiouBCDFGHJKLMNPQRSTVWXYZbcdfghjklmnpqrstvwxyz0123456789!@#$%^&*()";
break;
}
default: {
fprintf(stderr, "Unknown character class: %c", characterClass); fprintf(stderr, "Unknown character class: %c", characterClass);
abort(); abort();
} }
}
return classCharacters[seedByte % strlen(classCharacters)];
}

View File

@ -6,27 +6,27 @@
// Copyright (c) 2012 Lyndir. All rights reserved. // Copyright (c) 2012 Lyndir. All rights reserved.
// //
typedef NS_ENUM(NSUInteger, MPElementContentType) { typedef enum {
MPElementContentTypePassword, MPElementContentTypePassword,
MPElementContentTypeNote, MPElementContentTypeNote,
MPElementContentTypePicture, MPElementContentTypePicture,
}; } MPElementContentType;
typedef NS_ENUM(NSUInteger, MPElementTypeClass) { typedef enum {
/** Generate the password. */ /** Generate the password. */
MPElementTypeClassGenerated = 1 << 4, MPElementTypeClassGenerated = 1 << 4,
/** Store the password. */ /** Store the password. */
MPElementTypeClassStored = 1 << 5, MPElementTypeClassStored = 1 << 5,
}; } MPElementTypeClass;
typedef NS_ENUM(NSUInteger, MPElementFeature) { typedef enum {
/** Export the key-protected content data. */ /** Export the key-protected content data. */
MPElementFeatureExportContent = 1 << 10, MPElementFeatureExportContent = 1 << 10,
/** Never export content. */ /** Never export content. */
MPElementFeatureDevicePrivate = 1 << 11, MPElementFeatureDevicePrivate = 1 << 11,
}; } MPElementFeature;
typedef NS_ENUM(NSUInteger, MPElementType) { typedef enum {
MPElementTypeGeneratedMaximum = 0x0 | MPElementTypeClassGenerated | 0x0, MPElementTypeGeneratedMaximum = 0x0 | MPElementTypeClassGenerated | 0x0,
MPElementTypeGeneratedLong = 0x1 | MPElementTypeClassGenerated | 0x0, MPElementTypeGeneratedLong = 0x1 | MPElementTypeClassGenerated | 0x0,
MPElementTypeGeneratedMedium = 0x2 | MPElementTypeClassGenerated | 0x0, MPElementTypeGeneratedMedium = 0x2 | MPElementTypeClassGenerated | 0x0,
@ -36,7 +36,14 @@ typedef NS_ENUM(NSUInteger, MPElementType) {
MPElementTypeStoredPersonal = 0x0 | MPElementTypeClassStored | MPElementFeatureExportContent, MPElementTypeStoredPersonal = 0x0 | MPElementTypeClassStored | MPElementFeatureExportContent,
MPElementTypeStoredDevicePrivate = 0x1 | MPElementTypeClassStored | MPElementFeatureDevicePrivate, MPElementTypeStoredDevicePrivate = 0x1 | MPElementTypeClassStored | MPElementFeatureDevicePrivate,
}; } MPElementType;
extern const char *CipherForType(MPElementType type, char seedByte); #ifdef DEBUG
extern const char CharacterFromClass(char characterClass, char seedByte); #define trc(...) fprintf(stderr, __VA_ARGS__)
#else
#define trc(...) do {} while (0)
#endif
const MPElementType TypeWithName(const char *typeName);
const char *CipherForType(MPElementType type, uint8_t seedByte);
const char CharacterFromClass(char characterClass, uint8_t seedByte);