x509crypt.git

ref: 9ebba40a8a717394375e8bf1b2ff58189d990e98

./x509crypt


#! /bin/bash

# X509crypt (x509crypt) is Copyright (C) 2014-2021 Paolo Lulli, Kevwe Technology AB
#
# This file is part of x509crypt.
#
# x509crypt is free software: you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation, version 3.
#
# x509crypt is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
# GNU General Public License for more details.
#


CONFIG_DIR=$HOME/.x509crypt
GLOBAL_CONFIG=${CONFIG_DIR}/config


DEPENDENCIES="qrencode openssl"

setup_global_config(){
  echo "/C=GB/ST=London/L=London/O=Global Security/OU=IT Department"> ${GLOBAL_CONFIG}
  echo "Created config file: [${GLOBAL_CONFIG}]"
  exit 1
}

test -d $CONFIG_DIR || mkdir -p $CONFIG_DIR
test -f $GLOBAL_CONFIG || setup_global_config

generate_keys(){
  echo "GENERATE KEYS"
  profile=$1
  CONFIG_CERT_NAME=${profile}
  organization=$(cat ${GLOBAL_CONFIG})
  openssl genrsa -out $CONFIG_DIR/$profile/certs/$CONFIG_CERT_NAME.key 4096
  
  openssl req -batch -new -key $CONFIG_DIR/$profile/certs/$CONFIG_CERT_NAME.key \
  -subj "$organization/CN=$profile"\
  -out $CONFIG_DIR/$profile/certs/$CONFIG_CERT_NAME.csr
  
  openssl x509 -req -days 365 -in $CONFIG_DIR/$profile_name/certs/$CONFIG_CERT_NAME.csr \
  -signkey $CONFIG_DIR/$profile_name/certs/$CONFIG_CERT_NAME.key \
  -out $CONFIG_DIR/$profile_name/certs/$CONFIG_CERT_NAME.crt
}

export_key(){
  profile_name=$1
  CONFIG_CERT_NAME=${profile}

  test -f $CONFIG_CERT_NAME.key.enc && echo "ERROR: File already exist: [$CONFIG_CERT_NAME.key.enc]"
  test -f $CONFIG_CERT_NAME.key.enc && exit 1;

  genpassword=$(uuidgen)
  echo "----------------------------------------------------"
  echo ""
  echo "secret key password:[${genpassword}]"
  echo ""
  echo "----------------------------------------------------"
  echo ""
  qrencode "${genpassword}" -t UTF8

  openssl rsa -aes256 -in $CONFIG_DIR/$profile_name/certs/$CONFIG_CERT_NAME.key -out $CONFIG_CERT_NAME.key.enc -passout pass:${genpassword}
  echo "----------------------------------------------------"
  echo ""
  echo "secret key path:[$CONFIG_CERT_NAME.key.enc]"
  echo ""
  echo "----------------------------------------------------"
  echo ""
}

dependencies_check()
{
  for d in $DEPENDENCIES; do
    CHK=$(which $d)
    if [ "$CHK" = "" ]; then
      echo "missing deps: [$d]";
      exit 1
    fi
  done
}

export_certificate(){
  profile_name=$1
  CONFIG_CERT_NAME=${profile}
  cat $CONFIG_DIR/$profile_name/certs/$CONFIG_CERT_NAME.crt
}


dump_certificate(){
  profile_name=$1
  CONFIG_CERT_NAME=${profile}
  cat $CONFIG_DIR/$profile_name/certs/$CONFIG_CERT_NAME.crt | openssl x509 -text
}

setup_profile(){
  echo "SETUP PROFILE"
  profile_name=$1
  test -d $CONFIG_DIR/$profile_name || mkdir -p $CONFIG_DIR/$profile_name
  test -d $CONFIG_DIR/$profile_name/conf || mkdir -p $CONFIG_DIR/$profile_name/conf
  test -d $CONFIG_DIR/$profile_name/certs || mkdir -p $CONFIG_DIR/$profile_name/certs
}

file_decrypt(){
  #echo "FILE DECRYPT: $1"
  test -d $CONFIG_DIR/$profile_name || echo "profile: [$profile_name] does not exist, EXIT"
  test -d $CONFIG_DIR/$profile_name || exit 1
  decrypted_file=$1".cleartext"
  CONFIG_CERT_NAME=${profile_name}
  openssl smime -decrypt -binary -in $1 -inform DER -out $decrypted_file -inkey $CONFIG_DIR/$profile_name/certs/$CONFIG_CERT_NAME.key -passin pass:your_password
  #openssl smime -decrypt -binary -in $1 -inform DER -out $decrypted_file -inkey $CONFIG_DIR/$profile_name/certs/$CONFIG_CERT_NAME.key
}

file_encrypt(){
  #echo "FILE ENCRYPT: $1"
  file_size=$(du -s $1 | awk '{print $1}')
  
#  if [ ${file_size} -gt 500000 ]; then
#    echo "File too big to encrypt with smime"
#    exit 1
#  fi

  encrypted_file=$1".enc"
  CONFIG_CERT_NAME=${profile_name}
  openssl smime -encrypt -binary -aes-256-cbc -in $1 -out $encrypted_file  -outform DER $CONFIG_DIR/$profile_name/certs/$CONFIG_CERT_NAME.crt
  # NOT BINARY ! 
  #openssl smime -encrypt -aes-256-cbc -in $1 -out $encrypted_file  -outform PEM $CONFIG_DIR/$profile_name/certs/$CONFIG_CERT_NAME.crt
}

file_import(){
  echo "FILE IMPORT: $1"
  imported_file=$1
  CONFIG_CERT_NAME=${profile_name}

  test -f $CONFIG_DIR/$profile_name/certs/$CONFIG_CERT_NAME.crt && echo "profile: [$profile_name] exists, SKIPPING"
  test -f $CONFIG_DIR/$profile_name/certs/$CONFIG_CERT_NAME.crt && exit 1
  
  test -d $CONFIG_DIR/$profile_name || mkdir -p $CONFIG_DIR/$profile_name/certs
  
  cp ${imported_file} $CONFIG_DIR/$profile_name/certs/$CONFIG_CERT_NAME.crt
}


list_profiles(){
  echo "profiles"
  echo "--------"
  for i in $(ls $CONFIG_DIR  | sed -e s/config//); do echo ${i}; done
}

usage(){
  program=$(basename $0)
  echo "${program}  -e  : Encrypt  (safety checks)"
  echo "${program}  -E  : Encrypt "
  
  echo "${program}  -d  : Decrypt "
 
  echo "${program}  -g        : Generate keys"
  
  echo "${program}  -x        : eXport pub key"
  echo "${program}  -s        : export private key"
  echo "${program}  -X        : eXport pub key details"
  echo "${program}  -i  : Import pub key"
  echo "${program} -l                  : List profiles"
}

dependencies_check

if [ "$#" -gt 3 ]; then
  usage
  exit
fi
if [ "$#" -eq 0 ]; then
  usage
  exit
fi

if [ "$#" -eq 1 ]; then
  if [ "$1" == "-l" ]; then
    list_profiles
    exit
  fi
  if [ "$2" == "-x" ]; then
    export_certificate "${profile}"
    exit
  fi
  usage
fi

if [ "$#" -eq 2 ]; then
  profile=$1
  if [ "$2" == "-g" ]; then
    test -d $CONFIG_DIR/$profile && echo "profile: [$profile] exists, SKIPPING"
    test -d $CONFIG_DIR/$profile && exit 1

    setup_profile "${profile}"
    generate_keys "${profile}"
    exit
  fi
  if [ "$2" == "-x" ]; then
    export_certificate "${profile}"
    exit
  fi
  if [ "$2" == "-s" ]; then
    export_key "${profile}"
    exit
  fi
  if [ "$2" == "-X" ]; then
    dump_certificate "${profile}"
    exit
  fi
  
  usage
fi
if [ "$#" -eq 3 ]; then
  profile_name=$1
  input_file=$3
  if [ "$2" == "-E" ]; then
    file_encrypt $input_file
    exit
  fi
  if [ "$2" == "-e" ]; then
    file_encrypt $input_file
    file_decrypt $input_file".enc"
    diff $input_file $input_file".enc.cleartext" || echo "ERROR: BAD ENCRYPTION"
    rm $input_file".enc.cleartext"
    exit
  fi
  if [ "$2" == "-d" ]; then
    file_decrypt $input_file
    exit
  fi
  if [ "$2" == "-i" ]; then
    file_import $input_file
    exit
  fi

  usage
fi