Browse Source

Initial commit

master
dirkson 3 years ago
parent
commit
1d29025f3f
  1. 10
      README.md
  2. 271
      build
  3. 27
      include/simsecl.h
  4. 21
      meson.build
  5. 255
      src/simsecl.c

10
README.md

@ -1,3 +1,11 @@
# simsecl
Authentication framework
Simsecl is an authentication framework. A client hands login information to a server. If the information is correct, the server responds back with an 'authchit'. This authchit allows interested parties to verify authentication for a limited amount of time. Additional information can be embedded inside the authchit.
# libsimsecl
# server
# client-libui
# client-nuklear

271
build

@ -0,0 +1,271 @@
#!/bin/bash
#************
#***CONFIG***
#************
#If COMPILER isn't set, the script will attempt to figure it out itself.
#If you change the compiler, you'll need to clean your build.
#COMPILER=musl-gcc
#If this isn't set, the script will attempt to find ninja and samu, in that order.
#Alternatives include samurai's "samu"
#NINJACOMMAND=ninja
#Directories
BUILDDIR=meson
BINDIR=bin
LIBDIR=lib
DEPDIR=subprojects
SCRIPTDIR=scripts
#***********
#***OSMIA***
#***********
#
# This is osmia, a build script for meson.
#
# Official URL:
# https://git.orangehattech.com/dirkson/osmia
#
#*************
#***LICENSE***
#*************
#
# MIT License
#
# Copyright (c) 2018 Dirkson
#
# Permission is hereby granted, free of charge, to any person obtaining a copy
# of this software and associated documentation files (the "Software"), to deal
# in the Software without restriction, including without limitation the rights
# to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
# copies of the Software, and to permit persons to whom the Software is
# furnished to do so, subject to the following conditions:
#
# The above copyright notice and this permission notice shall be included in all
# copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
# IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
# FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
# AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
# LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
# OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
# SOFTWARE.
#
#Functions
osmia_help () {
echo "Osmia build script for meson."
echo "Usage: ./build [-mode] [target]"
echo "Target will be passed to ninja directly"
echo "Mode defaults to release, or is one of the following:"
echo "-r OR --release : Builds using Meson's release mode"
echo "-d OR --debug : Builds using Meson's debug mode, with --werror added"
echo "-c OR --clean : Cleans up current project meson/ninja/osmia files"
echo "-fc OR --full-clean : Fully clean - Removes dependencies too"
echo "-a OR --add-san : Clang's address sanitizer"
echo "-w OR --win : Cross-compile for win32 using scripts/win32cross.txt"
echo "-w64 OR --win64 : cross-compile for win64"
echo "-o OR --osx : cross-compile for OSX"
}
osmia_clean () {
rm -rf $BUILDDIR $BINDIR $LIBDIR
}
osmia_symlink () {
FILES="$(find $1 -maxdepth 1 -type f $2 2> /dev/null)"
if [ ! -z "$FILES" ]; then
mkdir -p $3 2> /dev/null
rm -rf $3/* 2> /dev/null
for I in $FILES; do
ln -s ../$I $3/
done
fi
}
osmia_get () {
if [ ! -d "$1" ]; then
$2
if [ ! $? -eq 0 ]; then
echo "Git command failed: $1"
exit 1
fi
if [ ! -d "$1" ]; then
echo "Could not find directory: $1"
exit 1
fi
fi
}
clear
err=0;
if [[ "${BASH_SOURCE[0]}" != "${0}" ]]; then
err=1
echo "Er... Yeah, don't source this file."
return 1
fi
#What type of build?
case "$1" in
-d|-debug|--debug)
DIR=debug
BLD=debug
MESONOPTS="--werror"
;;
-a)
DIR=debug
BLD=debug
MESONOPTS=-Db_sanitize=address
MESONOPTS="--werror"
;;
-w|-win|--win|-window|--windows)
DIR=release
BLD=release
MESONOPTS="--cross-file scripts/win32cross.txt"
;;
-w64|-win64|--win64|-windows64|--windows64)
DIR=release
BLD=release
MESONOPTS="--cross-file scripts/win64cross.txt"
;;
-c|-clean|--clean)
if [ "$#" -ne 1 ]; then
echo "You passed additional arguments to clean. I have no idea what you want. Did not clean."
exit 1
fi
osmia_clean
echo "Cleaned."
exit 0
;;
-fc|-fullclean|--fullclean|-full-clean|--full-clean)
if [ "$#" -ne 1 ]; then
echo "You passed additional arguments to clean. I have no idea what you want. Did not clean."
exit 1
fi
osmia_clean
rm -rf $DEPDIR
echo "Fully cleaned."
exit 0
;;
-?|-h|-help|--help)
osmia_help
err=1
;;
-r|--release|*)
DIR=release
BLD=release
;;
esac
#do some basic error checking for the user
if [ -z "$NINJACOMMAND" ]; then
NINJACOMMAND=ninja
if [ ! -x "$(command -v $NINJACOMMAND)" ]; then
NINJACOMMAND=samu
if [ ! -x "$(command -v $NINJACOMMAND)" ]; then
echo "Neither ninja nor samu are installed. One of the two is required to build."
echo "Please install either samurai's samu of ninja-build's ninja."
err=1;
fi
fi
else
if [ ! -x "$(command -v $NINJACOMMAND)" ]; then
echo "Manually specified ninja command not found"
err=1;
fi
fi
if [ ! -x "$(command -v meson)" ]; then
echo "Meson not installed. The meson build system is required to build, please install.";
err=1;
fi
if [ -z "$COMPILER" ]; then
if [ -x "$(command -v clang)" ]; then
COMPILER="clang"
elif [ -x "$(command -v musl-gcc)" ]; then
COMPILER="musl-gcc -static"
elif [ -x "$(command -v gcc)" ]; then
COMPILER="gcc"
elif [ -x "$(command -v tcc)" ]; then
COMPILER="tcc"
elif [ -x "$(command -v icc)" ]; then
COMPILER="icc"
else
echo "Unable to find any compiler at all. Please install one: clang, musl-gcc, gcc, tcc, icc"
err=1
fi
else
if [ ! -x "$(command -v $COMPILER)" ]; then
echo "Manually specified compiler does not exist. Failing."
err=1
fi
fi
if [ ! -x "$(command -v ccache)" ]; then
echo "ccache not installed. Installing it could speed the build up. Hint Hint.";
fi
if [ "$#" -gt 2 ]; then
echo "Too many parameters. Failing."
osmia_help
echo "Too many parameters. Failing."
err=1;
fi
#Note: For exit '0' is 'true' and '1' in 'false', in spite of all logic.
if [ $err -ne 0 ]; then
exit 1
fi
#Grab dependencies
if [ -d "$SCRIPTDIR" ] && [ -e scripts/dependencies ]; then
mkdir -p $DEPDIR 2> /dev/null
cd "$DEPDIR"
source ../scripts/dependencies
cd ../
fi
#Set up basic directory structure, if needed
mkdir -p $BUILDDIR 2> /dev/null
#MESONOPTS=MESONOPTS:"-Dc_args=$3"
if [ ! -d "$BUILDDIR/$DIR" ]; then
export CC="$COMPILER"
#Run meson if required
mkdir $BUILDDIR/$DIR
meson $BUILDDIR/$DIR $MESONOPTS --buildtype $BLD
if [ ! $? -eq 0 ]; then
#Generally an error here means we need to clean before the next run
tail $BUILDDIR/$DIR/meson/logs/meson-log.txt
cp $BUILDDIR/$DIR/meson/logs/meson-log.txt meson-log.txt
echo "Meson error! Log output to meson-log.txt"
osmia_clean
exit 1
fi
#else
#May wish to look into this in the future
#meson configure $MESONOPTS
fi
#Actually build
cd $BUILDDIR/$DIR
$NINJACOMMAND $2
if [ ! $? -eq 0 ]; then
cd ../../
exit 1
fi
cd ../../
#set up symlinks
osmia_symlink "$BUILDDIR/$DIR/*" "-name *.a -o -name *.so -o -name *.dll" $LIBDIR
osmia_symlink "$BUILDDIR/$DIR/*" "-not -name *.so -not -name *.dll -executable -not -name sanitycheckc.exe" $BINDIR
exit 0

27
include/simsecl.h

@ -0,0 +1,27 @@
#include <string.h>
#include <sodium.h>
unsigned char AuthPublicKey[crypto_box_PUBLICKEYBYTES];
unsigned char AuthSecretKey[crypto_box_SECRETKEYBYTES];
unsigned char AuthPublicSigningKey[crypto_sign_PUBLICKEYBYTES];
unsigned char AuthSecretSigningKey[crypto_sign_SECRETKEYBYTES];
void InitializeCryptography();
void DisplayPubKey(unsigned char *);
void DisplaySecKey(unsigned char *);
void DisplayPubSigningKey(unsigned char *);
void GenerateAndSaveKeypair(unsigned char *, unsigned char *);
void LoadKeypair(unsigned char *, unsigned char *);
void GenerateAndSaveSigningKeypair(unsigned char *, unsigned char *);
void LoadSigningKeypair(unsigned char *, unsigned char *);
unsigned char *SimseclDecrypt(const unsigned char *, unsigned long long*, const unsigned char *, const unsigned char *, unsigned char *);
//unsigned char *CreateAuthChit(const unsigned char *, PlayerAuthChitData*, char, unsigned int*);
#define SIMSECLAUTHCHITVALIDTIME 259200 //3 days

21
meson.build

@ -0,0 +1,21 @@
project('simsecl', 'c', default_options : ['default_library=static', 'c_std=c89'])
incdir = include_directories(['src', 'include'])
if get_option('buildtype').startswith('debug')
add_project_arguments('-DSIMSECL_DEBUG', language : 'c')
glslcopt = '-O0'
else
glslcopt = '-Os'
endif
executable('simsecl-tests', 'src/tests.c', include_directories : incdir)
executable('simsecl-client-libui', 'src/client-libui/main.c', include_directories : incdir)
executable('simsecl-client-nuklear', 'src/client-nuklear/main.c', include_directories : incdir)
executable('simsecl-server', 'src/server/main.c', include_directories : incdir)

255
src/simsecl.c

@ -0,0 +1,255 @@
#include "simsecl.h"
void InitializeCryptography()
{
sodium_init();
randombytes_stir(); //Needed?? It's cryptography, probably better safe than sorry.
// InitializeSrandSemiSecurely();
}
void GenerateAndSaveKeypair(unsigned char *PublicKey, unsigned char *SecretKey)
{
printf("Generating keypair\n");
crypto_box_keypair(PublicKey, SecretKey);
FILE *File;
// char FormatString[256];
// printf("OneLoc \n");
// sprintf(FormatString, "%%s.%d", 345);
// printf("Got to here. Formatstr: %s \n", FormatString);
// sprintf(FormatString, "%%s.%d", crypto_box_PUBLICKEYBYTES);
char *PublicKeyFileString = strdup("publickey");
File = fopen(PublicKeyFileString, "wb");
fwrite(PublicKey, 1, crypto_box_PUBLICKEYBYTES, File);
// fprintf(File, FormatString, PublicKey);
fclose(File);
free(PublicKeyFileString);
// sprintf(FormatString, "%%s.%d", crypto_box_SECRETKEYBYTES);
char *SecretKeyFileString = strdup("secretkey");
File = fopen(SecretKeyFileString, "wb");
fwrite(SecretKey, 1, crypto_box_SECRETKEYBYTES, File);
// fprintf(File, FormatString, SecretKey);
fclose(File);
free(SecretKeyFileString);
// printf("Finished generating keypair\n");
}
void GenerateAndSaveSigningKeypair(unsigned char *PublicKey, unsigned char *SecretKey)
{
printf("Generating signing keypair\n");
crypto_sign_keypair(PublicKey, SecretKey);
FILE *File;
char *PublicKeyFileString = strdup("publicsigningkey");
File = fopen(PublicKeyFileString, "wb");
fwrite(PublicKey, 1, crypto_sign_PUBLICKEYBYTES, File);
fclose(File);
free(PublicKeyFileString);
char *SecretKeyFileString = strdup("secretsigningkey");
File = fopen(SecretKeyFileString, "wb");
fwrite(SecretKey, 1, crypto_sign_SECRETKEYBYTES, File);
fclose(File);
free(SecretKeyFileString);
}
void DisplayPubSigningKey(unsigned char *PublicKey)
{
unsigned int i;
printf("Server PublicSigningKey:");
for(i = 0; i < crypto_sign_PUBLICKEYBYTES; i++)
printf(", %u", PublicKey[i]);
printf("\n");
}
void DisplayPubKey(unsigned char *PublicKey)
{
unsigned int i;
printf("Server PublicKey:");
for(i = 0; i < crypto_box_PUBLICKEYBYTES; i++)
printf(", %u", PublicKey[i]);
printf("\n");
}
void DisplaySecKey(unsigned char *SecretKey)
{
unsigned int i;
printf("Server SecretKey:");
for(i = 0; i < crypto_box_SECRETKEYBYTES; i++)
printf(" %u", SecretKey[i]);
printf("\n");
}
void LoadKeypair(unsigned char *PublicKey, unsigned char *SecretKey)
{
FILE *File;
char *PublicKeyFileString = strdup("publickey");
File = fopen(PublicKeyFileString, "rb");
fread(PublicKey, 1, crypto_box_PUBLICKEYBYTES, File);
//fscanf(File, "%s", PublicKey);
fclose(File);
free(PublicKeyFileString);
char *SecretKeyFileString = strdup("secretkey");
File = fopen(SecretKeyFileString, "rb");
fread(SecretKey, 1, crypto_box_SECRETKEYBYTES, File);
// fscanf(File, "%s", SecretKey);
fclose(File);
free(SecretKeyFileString);
}
void LoadSigningKeypair(unsigned char *PublicKey, unsigned char *SecretKey)
{
FILE *File;
char *PublicKeyFileString = strdup("publicsigningkey");
File = fopen(PublicKeyFileString, "rb");
fread(PublicKey, 1, crypto_sign_PUBLICKEYBYTES, File);
//fscanf(File, "%s", PublicKey);
fclose(File);
free(PublicKeyFileString);
char *SecretKeyFileString = strdup("secretsigningkey");
File = fopen(SecretKeyFileString, "rb");
fread(SecretKey, 1, crypto_sign_SECRETKEYBYTES, File);
// fscanf(File, "%s", SecretKey);
fclose(File);
free(SecretKeyFileString);
}
//SimseclEncrypt/decrypt mainly provide a way to obfuscate out the weirder parts of NaCL - Namely the zerobytes thing, and filling the nonce for me.
unsigned char *SimseclEncrypt(const char *Message, unsigned long long *Length, const unsigned char *SecretKey, const unsigned char *PublicKey, unsigned char *Nonce)
{
randombytes(Nonce, crypto_box_NONCEBYTES);
unsigned long long FinalLength = crypto_box_ZEROBYTES + *Length;
unsigned char *FinalMessage = (unsigned char*)calloc(FinalLength, 1);
memcpy(&FinalMessage[crypto_box_ZEROBYTES], Message, *Length);
// DisplayRawUnsignedCharArray("Encrypt Plaintext: ", (unsigned char *)Message, (int)*Length);
unsigned char *Return = (unsigned char*)calloc(FinalLength, 1);
crypto_box(Return, FinalMessage, FinalLength, Nonce, PublicKey, SecretKey);
// DisplayRawUnsignedCharArray("Encrypt Public Key:", (unsigned char*)PublicKey, crypto_box_PUBLICKEYBYTES);
// DisplayRawUnsignedCharArray("Encrypt Secret Key:", (unsigned char*)SecretKey, crypto_box_SECRETKEYBYTES);
// DisplayRawUnsignedCharArray("Encrypt Nonce: ", Nonce, crypto_box_NONCEBYTES);
// DisplayRawUnsignedCharArray("Encrypt Ciphertext:", Return, (int)FinalLength);
free(FinalMessage);
//Nonce is already filled, but let's update everything else.
*Length = FinalLength;
return Return;
}
unsigned char *SimseclDecrypt(const unsigned char *EncryptedMessage, unsigned long long *Length, const unsigned char *SecretKey, const unsigned char *PublicKey, unsigned char *Nonce)
{
unsigned char *Temp = (unsigned char*)calloc(*Length, 1);
DisplayRawUnsignedCharArray("Decrypt Public Key:", (unsigned char*)PublicKey, crypto_box_PUBLICKEYBYTES);
DisplayRawUnsignedCharArray("Decrypt Secret Key:", (unsigned char*)SecretKey, crypto_box_SECRETKEYBYTES);
DisplayRawUnsignedCharArray("Decrypt Nonce: ", Nonce, crypto_box_NONCEBYTES);
DisplayRawUnsignedCharArray("Decrypt Ciphertext:", (unsigned char*)EncryptedMessage, (int)*Length);
if (crypto_box_open(Temp, EncryptedMessage, *Length, Nonce, PublicKey, SecretKey) == -1)
{
printf("Could not decrypt!\n");
return 0;
}
*Length = *Length - crypto_box_ZEROBYTES;
unsigned char *Return = (unsigned char*)calloc(*Length, 1);
memcpy(Return, &Temp[crypto_box_ZEROBYTES], *Length);
free(Temp);
return Return;
}
//How long is an authchit? Bytes
// Publickey 32
// Encryption overhead 64
// Name 64
// Timestamp 4
// SubTotal 164
// Style ?
// For ease of integration with UDP packets, this should stay < 400 bytes total. (That gives us ~80 bytes spare to do other things with in a packet)
//Timestamp expiry should be 3 days.
//Encapsulate good-until timestamp, username, public key, deluxe/full status, preferred color, preferred hairstyle
/*
unsigned char *CreateAuthChit(const unsigned char *SecretKey, PlayerAuthChitData *PlayerMiscData, char KeyNumber, unsigned int *AuthChitLength)
{
//Allocate
unsigned long long Length = sizeof(int) + (strlen(PlayerMiscData->Username) + 1) + (strlen(PlayerMiscData->Style) + 1) + 2 + crypto_box_PUBLICKEYBYTES;
unsigned char *ChitMessage = (unsigned char *)malloc(Length);
unsigned long long SignedLength = Length + crypto_sign_BYTES;
unsigned char *SignedMessage = (unsigned char *)malloc(2 + SignedLength);
// time_t CurrentTime;
// time(&CurrentTime);
//Convert to struct, add three days
// struct tm *TimeStruct = gmtime(&CurrentTime);
// TimeStruct->tm_mday = TimeStruct->tm_mday + 3;
// time_t ExpirationTime = mktime(TimeStruct);
unsigned int i = 0;
// memcpy(&ChitMessage[i], &ExpirationTime, sizeof(int));
// i = i + sizeof(int);
AddIntToPacket((char *)ChitMessage, &i, ExpirationTime);
AddStringToPacket((char *)ChitMessage, &i, PlayerMiscData->Username);
// printf("Ungocac: %s \n", PlayerMiscData->Username);
AddStringToPacket((char *)ChitMessage, &i, PlayerMiscData->Style);
// Error("CreatedPubKey");
// DisplayRawCharArray(PlayerMiscData->PublicKey1, crypto_box_PUBLICKEYBYTES);
if (KeyNumber == 1)
AddSetLengthDataBlobToPacket((char *)ChitMessage, &i, PlayerMiscData->PublicKey1, crypto_box_PUBLICKEYBYTES);
else if (KeyNumber == 2)
AddSetLengthDataBlobToPacket((char *)ChitMessage, &i, PlayerMiscData->PublicKey2, crypto_box_PUBLICKEYBYTES);
else if (KeyNumber == 3)
AddSetLengthDataBlobToPacket((char *)ChitMessage, &i, PlayerMiscData->PublicKey3, crypto_box_PUBLICKEYBYTES);
// DisplayRawCharArray(ChitMessage, Length);
//Sign
crypto_sign(&SignedMessage[2],&SignedLength,ChitMessage,Length,SecretKey);
//Prepend the length of out authchit onto the front of our authchit
unsigned short int *LengthPointer = (unsigned short int *)&SignedMessage[0];
*LengthPointer = SignedLength;
// printf("wigowl: %i %i \n", SignedLength, *LengthPointer);
*AuthChitLength = 2 + SignedLength;
//Cleanup
free(ChitMessage);
return SignedMessage;
}
*/
Loading…
Cancel
Save