Finished the C implementation & CLI tool. Providing an OS X binary.
This commit is contained in:
parent
cf9dabcc82
commit
d732b03828
1
.gitignore
vendored
1
.gitignore
vendored
@ -29,6 +29,7 @@ Press/MasterPassword_PressKit/MasterPassword_pressrelease_*.pdf
|
|||||||
MasterPassword/Java/**/target
|
MasterPassword/Java/**/target
|
||||||
|
|
||||||
# C
|
# C
|
||||||
|
MasterPassword/C/*.o
|
||||||
MasterPassword/C/mpw
|
MasterPassword/C/mpw
|
||||||
MasterPassword/C/lib/*/*
|
MasterPassword/C/lib/*/*
|
||||||
!MasterPassword/C/lib/*/.source
|
!MasterPassword/C/lib/*/.source
|
||||||
|
2
External/LoveLyndir
vendored
2
External/LoveLyndir
vendored
@ -1 +1 @@
|
|||||||
Subproject commit ceed9e20009f2cf3679445e2c60b0f206aaef383
|
Subproject commit 77e8fa376e3b28224ca26e08146242b71269567c
|
1920
MasterPassword/C/bashlib
Executable file
1920
MasterPassword/C/bashlib
Executable file
File diff suppressed because it is too large
Load Diff
@ -1,5 +1,9 @@
|
|||||||
#!/usr/bin/env bash -e
|
#!/usr/bin/env bash -e
|
||||||
# Run with -DDEBUG to enable trace-level output.
|
# Run with -DDEBUG to enable trace-level output.
|
||||||
|
|
||||||
gcc -c types.c -o types.o "$@"
|
[[ -e lib/scrypt/scryptenc.o ]] || { echo >&2 "Missing scrypt. First get and build the scrypt source in lib/scrypt from <$(<lib/scrypt/.source)>.\n"; exit 1; }
|
||||||
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 "$@"
|
|
||||||
|
deps=( -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"crypto" -L"." -L"lib/scrypt" )
|
||||||
|
|
||||||
|
gcc "${deps[@]}" -Qunused-arguments -c types.c -o types.o "$@"
|
||||||
|
gcc "${deps[@]}" -Qunused-arguments -l"types.o" mpw.c -o mpw "$@"
|
||||||
|
@ -1,78 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="UTF-8"?>
|
|
||||||
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
|
|
||||||
<plist version="1.0">
|
|
||||||
<dict>
|
|
||||||
<key>MPElementGeneratedEntity</key>
|
|
||||||
<dict>
|
|
||||||
<key>Maximum Security Password</key>
|
|
||||||
<array>
|
|
||||||
<string>anoxxxxxxxxxxxxxxxxx</string>
|
|
||||||
<string>axxxxxxxxxxxxxxxxxno</string>
|
|
||||||
</array>
|
|
||||||
<key>Long Password</key>
|
|
||||||
<array>
|
|
||||||
<string>CvcvnoCvcvCvcv</string>
|
|
||||||
<string>CvcvCvcvnoCvcv</string>
|
|
||||||
<string>CvcvCvcvCvcvno</string>
|
|
||||||
<string>CvccnoCvcvCvcv</string>
|
|
||||||
<string>CvccCvcvnoCvcv</string>
|
|
||||||
<string>CvccCvcvCvcvno</string>
|
|
||||||
<string>CvcvnoCvccCvcv</string>
|
|
||||||
<string>CvcvCvccnoCvcv</string>
|
|
||||||
<string>CvcvCvccCvcvno</string>
|
|
||||||
<string>CvcvnoCvcvCvcc</string>
|
|
||||||
<string>CvcvCvcvnoCvcc</string>
|
|
||||||
<string>CvcvCvcvCvccno</string>
|
|
||||||
<string>CvccnoCvccCvcv</string>
|
|
||||||
<string>CvccCvccnoCvcv</string>
|
|
||||||
<string>CvccCvccCvcvno</string>
|
|
||||||
<string>CvcvnoCvccCvcc</string>
|
|
||||||
<string>CvcvCvccnoCvcc</string>
|
|
||||||
<string>CvcvCvccCvccno</string>
|
|
||||||
<string>CvccnoCvcvCvcc</string>
|
|
||||||
<string>CvccCvcvnoCvcc</string>
|
|
||||||
<string>CvccCvcvCvccno</string>
|
|
||||||
</array>
|
|
||||||
<key>Medium Password</key>
|
|
||||||
<array>
|
|
||||||
<string>CvcnoCvc</string>
|
|
||||||
<string>CvcCvcno</string>
|
|
||||||
</array>
|
|
||||||
<key>Basic Password</key>
|
|
||||||
<array>
|
|
||||||
<string>aaanaaan</string>
|
|
||||||
<string>aannaaan</string>
|
|
||||||
<string>aaannaaa</string>
|
|
||||||
</array>
|
|
||||||
<key>Short Password</key>
|
|
||||||
<array>
|
|
||||||
<string>Cvcn</string>
|
|
||||||
</array>
|
|
||||||
<key>PIN</key>
|
|
||||||
<array>
|
|
||||||
<string>nnnn</string>
|
|
||||||
</array>
|
|
||||||
</dict>
|
|
||||||
<key>MPCharacterClasses</key>
|
|
||||||
<dict>
|
|
||||||
<key>V</key>
|
|
||||||
<string>AEIOU</string>
|
|
||||||
<key>C</key>
|
|
||||||
<string>BCDFGHJKLMNPQRSTVWXYZ</string>
|
|
||||||
<key>v</key>
|
|
||||||
<string>aeiou</string>
|
|
||||||
<key>c</key>
|
|
||||||
<string>bcdfghjklmnpqrstvwxyz</string>
|
|
||||||
<key>A</key>
|
|
||||||
<string>AEIOUBCDFGHJKLMNPQRSTVWXYZ</string>
|
|
||||||
<key>a</key>
|
|
||||||
<string>AEIOUaeiouBCDFGHJKLMNPQRSTVWXYZbcdfghjklmnpqrstvwxyz</string>
|
|
||||||
<key>n</key>
|
|
||||||
<string>0123456789</string>
|
|
||||||
<key>o</key>
|
|
||||||
<string>@&%?,=[]_:-+*$#!'^~;()/.</string>
|
|
||||||
<key>x</key>
|
|
||||||
<string>AEIOUaeiouBCDFGHJKLMNPQRSTVWXYZbcdfghjklmnpqrstvwxyz0123456789!@#$%^&*()</string>
|
|
||||||
</dict>
|
|
||||||
</dict>
|
|
||||||
</plist>
|
|
@ -1,15 +1,53 @@
|
|||||||
#!/usr/bin/env bash
|
#!/usr/bin/env bash
|
||||||
BINDIR=${BINDIR:+${PREFIX:+$PREFIX/bin}}
|
#
|
||||||
[[ $BINDIR ]] && mkdir -p "$BINDIR"
|
# Install the Master Password CLI tool.
|
||||||
if [[ ! -w $BINDIR ]]; then
|
set -e
|
||||||
for dir in /usr/local/bin ~/.bin ~/bin /usr/bin; do
|
cd "${BASH_SOURCE%/*}"
|
||||||
[[ -w $dir ]] && BINDIR=$dir && break
|
source bashlib
|
||||||
done
|
|
||||||
if [[ ! -w $BINDIR ]]; then
|
inf "This will install the mpw tool."
|
||||||
echo >&2 "Could not find directory to install to."
|
|
||||||
echo >&2 "You can specify a prefix to install to, eg. PREFIX=/usr/local ./install"
|
# Try to guess then ask for the bin dir to install to.
|
||||||
echo >&2 "You can specify a bin directory to install to, eg. BINDIR=~/bin ./install"
|
IFS=: read -a paths <<< "$PATH"
|
||||||
echo >&2 "Make sure you have write permission to the bin directory."
|
if inArray ~/bin "${paths[@]}"; then
|
||||||
fi
|
bindir=~/bin
|
||||||
|
elif inArray ~/.bin "${paths[@]}"; then
|
||||||
|
bindir=~/.bin
|
||||||
|
elif inArray /usr/local/bin "${paths[@]}"; then
|
||||||
|
bindir=/usr/local/bin
|
||||||
|
else
|
||||||
|
bindir=~/bin
|
||||||
fi
|
fi
|
||||||
install -v -s mpw "$BINDIR"
|
bindir=$(ask -d "$bindir" "What bin directory should I install to?")
|
||||||
|
[[ -d "$bindir" ]] || mkdir "$bindir" || ftl 'Cannot create missing bin directory: %s' "$bindir" || exit
|
||||||
|
[[ -w "$bindir" ]] || ftl 'Cannot write to bin directory: %s' "$bindir" || exit
|
||||||
|
|
||||||
|
# Install Master Password.
|
||||||
|
install mpw "$bindir"
|
||||||
|
[[ ! -e "$bindir/bashlib" ]] && install bashlib "$bindir" ||:
|
||||||
|
|
||||||
|
# Convenience bash function.
|
||||||
|
inf "Installation successful!"
|
||||||
|
echo
|
||||||
|
|
||||||
|
inf "To improve usability, you can install an mpw function in your bash shell."
|
||||||
|
inf "This function adds the following features:"
|
||||||
|
inf " - Automatically remember your user name in the shell if not set."
|
||||||
|
inf " - Automatically put the password in the clipboard (some platforms)."
|
||||||
|
echo
|
||||||
|
inf "To do this you need the following function in ~/.bashrc:\n%s" "$(<mpw.bashrc)"
|
||||||
|
echo
|
||||||
|
inf "We can do this for you automatically now."
|
||||||
|
if ask -c Y!n "Append the mpw function to your .bashrc?"; then
|
||||||
|
cat mpw.bashrc >> ~/.bashrc
|
||||||
|
inf "Done! Don't forget to run '%s' to apply the changes!" "source ~/.bashrc"
|
||||||
|
fi
|
||||||
|
echo
|
||||||
|
|
||||||
|
inf "You can also save your user name in ~/.bashrc. Leave blank to skip this step."
|
||||||
|
if MP_USERNAME=$(ask "Your full name:") && [[ $MP_USERNAME ]] ; then
|
||||||
|
printf 'export MP_USERNAME=%q\n' "$MP_USERNAME" >> ~/.bashrc
|
||||||
|
fi
|
||||||
|
echo
|
||||||
|
|
||||||
|
inf "To begin using Master Password, type: mpw [site name]"
|
||||||
|
@ -1 +0,0 @@
|
|||||||
https://code.google.com/p/portableproplib/
|
|
24
MasterPassword/C/mpw.bashrc
Normal file
24
MasterPassword/C/mpw.bashrc
Normal file
@ -0,0 +1,24 @@
|
|||||||
|
## Added by Master Password
|
||||||
|
source bashlib
|
||||||
|
mpw() {
|
||||||
|
_copy() {
|
||||||
|
if hash pbcopy 2>/dev/null; then
|
||||||
|
pbcopy
|
||||||
|
elif hash xclip 2>/dev/null; then
|
||||||
|
xclip
|
||||||
|
else
|
||||||
|
cat
|
||||||
|
return
|
||||||
|
fi
|
||||||
|
echo >&2 "Copied!"
|
||||||
|
}
|
||||||
|
|
||||||
|
# Empty the clipboard
|
||||||
|
:| _copy 2>/dev/null
|
||||||
|
|
||||||
|
# Ask for the user's name and password if not yet known.
|
||||||
|
MP_USERNAME=${MP_USERNAME:-$(ask -s 'Your Full Name:')}
|
||||||
|
|
||||||
|
# Start Master Password and copy the output.
|
||||||
|
printf %s "$(MP_USERNAME=$MP_USERNAME command mpw "$@")" | _copy
|
||||||
|
}
|
@ -32,6 +32,23 @@
|
|||||||
#define MP_env_sitetype "MP_SITETYPE"
|
#define MP_env_sitetype "MP_SITETYPE"
|
||||||
#define MP_env_sitecounter "MP_SITECOUNTER"
|
#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);
|
||||||
|
fprintf(stderr, " -t type Specify the password's template.\n"
|
||||||
|
" Defaults to %s in env or 'long'.\n"
|
||||||
|
" x, max, maximum | 20 characters, contains symbols.\n"
|
||||||
|
" l, long | Copy-friendly, 14 characters, contains symbols.\n"
|
||||||
|
" m, med, medium | Copy-friendly, 8 characters, contains symbols.\n"
|
||||||
|
" b, basic | 8 characters, no symbols.\n"
|
||||||
|
" s, short | Copy-friendly, 4 characters, no symbols.\n"
|
||||||
|
" p, pin | 4 numbers.\n\n", MP_env_sitetype);
|
||||||
|
fprintf(stderr, " -c counter The value of the counter.\n"
|
||||||
|
" Defaults to %s in env or '1'.\n\n", MP_env_sitecounter);
|
||||||
|
exit(0);
|
||||||
|
}
|
||||||
|
|
||||||
char *homedir(const char *filename) {
|
char *homedir(const char *filename) {
|
||||||
char *homedir = NULL;
|
char *homedir = NULL;
|
||||||
#if defined(__CYGWIN__)
|
#if defined(__CYGWIN__)
|
||||||
@ -59,6 +76,9 @@ char *homedir(const char *filename) {
|
|||||||
|
|
||||||
int main(int argc, char *const argv[]) {
|
int main(int argc, char *const argv[]) {
|
||||||
|
|
||||||
|
if (argc < 2)
|
||||||
|
usage();
|
||||||
|
|
||||||
// Read the environment.
|
// Read the environment.
|
||||||
const char *userName = getenv( MP_env_username );
|
const char *userName = getenv( MP_env_username );
|
||||||
const char *masterPassword = NULL;
|
const char *masterPassword = NULL;
|
||||||
@ -70,8 +90,11 @@ int main(int argc, char *const argv[]) {
|
|||||||
|
|
||||||
// Read the options.
|
// Read the options.
|
||||||
char opt;
|
char opt;
|
||||||
while ((opt = getopt(argc, argv, "u:t:c:")) != -1)
|
while ((opt = getopt(argc, argv, "u:t:c:h")) != -1)
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
|
case 'h':
|
||||||
|
usage();
|
||||||
|
break;
|
||||||
case 'u':
|
case 'u':
|
||||||
userName = optarg;
|
userName = optarg;
|
||||||
break;
|
break;
|
||||||
@ -142,7 +165,7 @@ int main(int argc, char *const argv[]) {
|
|||||||
ssize_t linelen;
|
ssize_t linelen;
|
||||||
while ((linelen = getline(&line, &linecap, mpwConfig)) > 0)
|
while ((linelen = getline(&line, &linecap, mpwConfig)) > 0)
|
||||||
if (strcmp(strsep(&line, ":"), userName) == 0) {
|
if (strcmp(strsep(&line, ":"), userName) == 0) {
|
||||||
masterPassword = line;
|
masterPassword = strsep(&line, "\n");
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
if (!masterPassword) {
|
if (!masterPassword) {
|
||||||
@ -151,47 +174,75 @@ int main(int argc, char *const argv[]) {
|
|||||||
}
|
}
|
||||||
trc("masterPassword: %s\n", masterPassword);
|
trc("masterPassword: %s\n", masterPassword);
|
||||||
|
|
||||||
|
// Calculate the master key salt.
|
||||||
|
char *mpNameSpace = "com.lyndir.masterpassword";
|
||||||
|
const uint32_t n_userNameLength = htonl(strlen(userName));
|
||||||
|
size_t masterKeySaltLength = strlen(mpNameSpace) + sizeof(n_userNameLength) + strlen(userName);
|
||||||
|
char *masterKeySalt = malloc( masterKeySaltLength );
|
||||||
|
if (!masterKeySalt) {
|
||||||
|
fprintf(stderr, "Could not allocate master key salt: %d\n", errno);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
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);
|
||||||
|
if (mKS - masterKeySalt != masterKeySaltLength)
|
||||||
|
abort();
|
||||||
|
trc("masterKeySalt ID: %s\n", IDForBuf(masterKeySalt, masterKeySaltLength));
|
||||||
|
|
||||||
// Calculate the master key.
|
// Calculate the master key.
|
||||||
uint8_t *masterKey = malloc( MP_dkLen );
|
uint8_t *masterKey = malloc( MP_dkLen );
|
||||||
if (!masterKey) {
|
if (!masterKey) {
|
||||||
fprintf(stderr, "Could not allocate master key: %d\n", errno);
|
fprintf(stderr, "Could not allocate master key: %d\n", errno);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
const uint32_t n_userNameLength = htonl(strlen(userName));
|
|
||||||
char *masterKeySalt = NULL;
|
|
||||||
size_t masterKeySaltLength = asprintf(&masterKeySalt, "com.lyndir.masterpassword%s%s", (const char *) &n_userNameLength, userName);
|
|
||||||
if (!masterKeySalt) {
|
|
||||||
fprintf(stderr, "Could not allocate master key salt: %d\n", errno);
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
if (crypto_scrypt( (const uint8_t *)masterPassword, strlen(masterPassword), (const uint8_t *)masterKeySalt, masterKeySaltLength, MP_N, MP_r, MP_p, masterKey, MP_dkLen ) < 0) {
|
if (crypto_scrypt( (const uint8_t *)masterPassword, strlen(masterPassword), (const uint8_t *)masterKeySalt, masterKeySaltLength, MP_N, MP_r, MP_p, masterKey, MP_dkLen ) < 0) {
|
||||||
fprintf(stderr, "Could not generate master key: %d\n", errno);
|
fprintf(stderr, "Could not generate master key: %d\n", errno);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
memset(masterKeySalt, 0, masterKeySaltLength);
|
memset(masterKeySalt, 0, masterKeySaltLength);
|
||||||
free(masterKeySalt);
|
free(masterKeySalt);
|
||||||
|
trc("masterPassword Hex: %s\n", Hex(masterPassword, strlen(masterPassword)));
|
||||||
|
trc("masterPassword ID: %s\n", IDForBuf(masterPassword, strlen(masterPassword)));
|
||||||
|
trc("masterKey ID: %s\n", IDForBuf(masterKey, MP_dkLen));
|
||||||
|
|
||||||
// Calculate the site seed.
|
// Calculate the site seed.
|
||||||
const uint32_t n_siteCounter = htonl(siteCounter), n_siteNameLength = htonl(strlen(siteName));
|
const uint32_t n_siteNameLength = htonl(strlen(siteName));
|
||||||
char *sitePasswordInfo = NULL;
|
const uint32_t n_siteCounter = htonl(siteCounter);
|
||||||
size_t sitePasswordInfoLength = asprintf(&sitePasswordInfo, "com.lyndir.masterpassword%s%s%s", (const char *) &n_siteNameLength, siteName, (const char *) &n_siteCounter);
|
size_t sitePasswordInfoLength = strlen(mpNameSpace) + sizeof(n_siteNameLength) + strlen(siteName) + sizeof(n_siteCounter);
|
||||||
|
char *sitePasswordInfo = malloc( sitePasswordInfoLength );
|
||||||
if (!sitePasswordInfo) {
|
if (!sitePasswordInfo) {
|
||||||
fprintf(stderr, "Could not allocate site seed: %d\n", errno);
|
fprintf(stderr, "Could not allocate site seed: %d\n", errno);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char *sPI = sitePasswordInfo;
|
||||||
|
memcpy(sPI, mpNameSpace, strlen(mpNameSpace)); sPI += strlen(mpNameSpace);
|
||||||
|
memcpy(sPI, &n_siteNameLength, sizeof(n_siteNameLength)); sPI += sizeof(n_siteNameLength);
|
||||||
|
memcpy(sPI, siteName, strlen(siteName)); sPI += strlen(siteName);
|
||||||
|
memcpy(sPI, &n_siteCounter, sizeof(n_siteCounter)); sPI += sizeof(n_siteCounter);
|
||||||
|
if (sPI - sitePasswordInfo != sitePasswordInfoLength)
|
||||||
|
abort();
|
||||||
|
trc("seed from: hmac-sha256(masterKey, 'com.lyndir.masterpassword' | %s | %s | %s)\n", Hex(&n_siteNameLength, sizeof(n_siteNameLength)), siteName, Hex(&n_siteCounter, sizeof(n_siteCounter)));
|
||||||
|
trc("sitePasswordInfo ID: %s\n", IDForBuf(sitePasswordInfo, sitePasswordInfoLength));
|
||||||
|
|
||||||
uint8_t sitePasswordSeed[32];
|
uint8_t sitePasswordSeed[32];
|
||||||
HMAC_SHA256_Buf(masterKey, MP_dkLen, sitePasswordInfo, sitePasswordInfoLength, sitePasswordSeed);
|
HMAC_SHA256_Buf(masterKey, MP_dkLen, sitePasswordInfo, sitePasswordInfoLength, sitePasswordSeed);
|
||||||
memset(masterKey, 0, MP_dkLen);
|
memset(masterKey, 0, MP_dkLen);
|
||||||
memset(sitePasswordInfo, 0, sitePasswordInfoLength);
|
memset(sitePasswordInfo, 0, sitePasswordInfoLength);
|
||||||
free(masterKey);
|
free(masterKey);
|
||||||
free(sitePasswordInfo);
|
free(sitePasswordInfo);
|
||||||
|
trc("sitePasswordSeed ID: %s\n", IDForBuf(sitePasswordSeed, 32));
|
||||||
|
|
||||||
// Determine the cipher.
|
// Determine the cipher.
|
||||||
const char *cipher = CipherForType(siteType, sitePasswordSeed[0]);
|
const char *cipher = CipherForType(siteType, sitePasswordSeed[0]);
|
||||||
trc("type %s, cipher: %s\n", siteTypeString, cipher);
|
trc("type %s, cipher: %s\n", siteTypeString, cipher);
|
||||||
|
if (strlen(cipher) > 32)
|
||||||
|
abort();
|
||||||
|
|
||||||
// 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.");
|
|
||||||
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) {
|
||||||
sitePassword[c] = CharacterFromClass(cipher[c], sitePasswordSeed[c + 1]);
|
sitePassword[c] = CharacterFromClass(cipher[c], sitePasswordSeed[c + 1]);
|
||||||
|
@ -10,6 +10,9 @@
|
|||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
|
|
||||||
|
#include <alg/sha256.h>
|
||||||
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
|
|
||||||
const MPElementType TypeWithName(const char *typeName) {
|
const MPElementType TypeWithName(const char *typeName) {
|
||||||
@ -118,4 +121,20 @@ const char CharacterFromClass(char characterClass, uint8_t seedByte) {
|
|||||||
|
|
||||||
return classCharacters[seedByte % strlen(classCharacters)];
|
return classCharacters[seedByte % strlen(classCharacters)];
|
||||||
}
|
}
|
||||||
|
const char *IDForBuf(const void *buf, size_t length) {
|
||||||
|
uint8_t hash[32];
|
||||||
|
SHA256_Buf(buf, length, hash);
|
||||||
|
|
||||||
|
char *id = calloc(65, sizeof(char));
|
||||||
|
for (int kH = 0; kH < 32; kH++)
|
||||||
|
sprintf(&(id[kH * 2]), "%02X", hash[kH]);
|
||||||
|
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
|
||||||
|
const char *Hex(const void *buf, size_t length) {
|
||||||
|
char *id = calloc(length*2+1, sizeof(char));
|
||||||
|
for (int kH = 0; kH < length; kH++)
|
||||||
|
sprintf(&(id[kH * 2]), "%02X", ((const uint8_t*)buf)[kH]);
|
||||||
|
return id;
|
||||||
|
}
|
||||||
|
@ -47,3 +47,6 @@ typedef enum {
|
|||||||
const MPElementType TypeWithName(const char *typeName);
|
const MPElementType TypeWithName(const char *typeName);
|
||||||
const char *CipherForType(MPElementType type, uint8_t seedByte);
|
const char *CipherForType(MPElementType type, uint8_t seedByte);
|
||||||
const char CharacterFromClass(char characterClass, 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);
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user