diff --git a/.drone.yml b/.drone.yml index 3a4313b..a4746a8 100644 --- a/.drone.yml +++ b/.drone.yml @@ -25,4 +25,4 @@ steps: PLUGIN_CHMOD: false #PLUGIN_DEBUG: false PLUGIN_INCLUDE: ^smt$,^smt_checksum.txt$ - PLUGIN_EXCLUDE: ^\.git/$,^\uim2/$,^\controllers/$,^\middlewares/$,^\models/$,^\utils/$ \ No newline at end of file + PLUGIN_EXCLUDE: ^\.git/$,^\controllers/$,^\middlewares/$,^\models/$,^\utils/$ \ No newline at end of file diff --git a/api-test.sh b/api-test.sh new file mode 100644 index 0000000..bc9763c --- /dev/null +++ b/api-test.sh @@ -0,0 +1,619 @@ +#!/bin/bash +set -o pipefail + +VERSION='0.3.0' +RED=$(tput setaf 1) +GREEN=$(tput setaf 2) +BOLD=$(tput bold) +UNDERLINE=$(tput smul) +RESET=$(tput sgr 0) + +ACTION="" + +FILE="" + +VERBOSE=0 + +COMMAND_NAME="api-test" + +ACCESS_TOKEN="" +ID_TOKEN="" +URL="" + +SHOW_HEADER=0 +SUPER_SILENT=0 +HEADER_ONLY=0 +SILENT=0 +API_ERROR=0 + +# Helper methods +echo_v() { + if [ $VERBOSE -eq 1 ]; then + echo $1 + fi +} + +echo_t() { + printf "\t%s\n" "$1" +} + +bytes_to_human() { + b=${1:-0} + d='' + s=0 + S=(Bytes {K,M,G,T,E,P,Y,Z}B) + while ((b > 1024)); do + d="$(printf ".%02d" $((b % 1024 * 100 / 1024)))" + b=$((b / 1024)) + let s++ + done + echo "$b$d ${S[$s]}" +} + +color_response() { + case $1 in + 2[0-9][0-9]) echo $GREEN ;; + [45][0-9][0-9]) echo $RED ;; + *) ;; + esac +} + +# Show usage +function usage() { + case $1 in + run) + echo "Run test cases specified in the test file." + echo "" + echo "USAGE: $COMMAND_NAME [-v] -f file_name run [-hiIs] [ARGS]" + echo "" + echo "OPTIONS:" + echo " -h (--help) print this message" + echo " -i (--include) include header" + echo " -I (--header-only) header only" + echo " -s (--silent) print response status and message only" + echo " -S (--super-silent) print response only" + echo "" + echo "ARGS:" + echo " all Run all test case." + echo " Run provided test case." + echo "" + echo "EXAMPLE:" + echo "'api-test -f test.json run test_case_1 test_case_2', 'api-test -f test.json run all'" + exit + ;; + test) + echo "Run automated tests for a test case." + echo "" + echo "USAGE: $COMMAND_NAME [-v] -f file_name test [ARGS]" + echo "" + echo "OPTIONS:" + echo " -h (--help) print this message" + echo "" + echo "ARGS:" + echo " all Run all automated tests." + echo " Run provided automated test." + echo "" + echo "EXAMPLE:" + echo "'api-test -f test.json test test_case_1 test_case_2', 'api-test -f test.json test all'" + exit + ;; + describe) + echo "List test cases or describe the contents in a test case." + echo "" + echo "USAGE: $COMMAND_NAME [-v] -f file_name describe [ARGS]" + echo "" + echo "OPTIONS:" + echo " -h (--help) print this message" + echo "" + echo "ARGS:" + echo " List all test case." + echo " Describe a test case." + echo " Describe a test case property using json path." + echo "" + echo "EXAMPLE:" + echo "'api-test -f test.json describe', 'api-test -f test.json describe test_case_1', 'api-test -f test.json describe test_case_1 body' " + exit + ;; + *) + echo "A simple program to test JSON APIs." + echo "" + echo "USAGE: $COMMAND_NAME [-hv] -f file_name [CMD] [ARGS]" + echo "" + echo "OPTIONS:" + echo " -h (--help) print this message" + echo " -v (--verbose) verbose logging" + echo " -f (--file) file to test" + echo " --version print the version of the program" + echo "" + echo "COMMANDS:" + echo " run Run test cases specified in the test file." + echo " test Run automated test in the test file." + echo " describe List test cases or describe the contents in a test case." + echo "" + echo "Run 'api-test COMMAND --help' for more information on a command." + exit + ;; + esac +} + +# api methods +call_api() { + ROUTE=$(jq -r ".testCases.\"$1\".path" $FILE) + BODY="$(jq -r ".testCases.\"$1\" | select(.body != null) | .body" $FILE)" + QUERY_PARAMS=$(cat $FILE | jq -r ".testCases.\"$1\" | select(.query != null) | .query | to_entries | map(\"\(.key)=\(.value|tostring)\") | join(\"&\") | \"?\" + . ") + REQUEST_HEADER=$(cat $FILE | jq -r ".testCases.\"$1\" | .header | if . != null then . else {} end | to_entries | map(\"\(.key): \(.value|tostring)\") | join(\"\n\") | if ( . | length) != 0 then \"-H\" + . else \"-H \" end") + METHOD="$(jq -r ".testCases.\"$1\".method //\"GET\" | ascii_upcase" $FILE)" + # curl -ivs --request $METHOD "$URL$ROUTE$QUERY_PARAMS" \ + # --data "$BODY" \ + # "$COMMON_HEADER" \ + # "$REQUEST_HEADER" \ + # -w '\n{ "ResponseTime": "%{time_total}s" }\n' + local raw_output=$(curl -is -k --request $METHOD "$URL$ROUTE$QUERY_PARAMS" \ + --data "$BODY" \ + "$COMMON_HEADER" \ + "$REQUEST_HEADER" \ + -w '\n{ "ResponseTime": "%{time_total}s", "Size": %{size_download} }' || echo "AUTO_API_ERROR") + + if [[ $raw_output == *"AUTO_API_ERROR"* ]]; then + echo "Problem connecting to $URL$ROUTE$QUERY_PARAMS" + #echo "COMMON_HEADER : $COMMON_HEADER" + #echo "REQUEST_HEADER : $REQUEST_HEADER" + #echo $raw_output + API_ERROR=1 + return 1 + fi + local header="$(awk -v bl=1 'bl{bl=0; h=($0 ~ /HTTP\//)} /^\r?$/{bl=1} {if(h)print $0 }' <<<"$raw_output")" + local json=$(jq -c -R -r '. as $line | try fromjson' <<<"$raw_output") + #echo "JSON body: '${json}'" + RESPONSE_BODY=$(sed -n 1p <<<"$json") + echo "RESPONSE body: '${RESPONSE_BODY}'" + META=$(sed 1d <<<"$json") + META=$(jq -r ".Size = \"$(bytes_to_human $(jq -r '.Size' <<<"$META"))\"" <<<"$META") + parse_header "$header" +} + +parse_header() { + local RESPONSE=($(echo "$header" | tr '\r' ' ' | sed -n 1p)) + local header=$(echo "$header" | sed '1d;$d' | sed 's/: /" : "/' | sed 's/^/"/' | tr '\r' ' ' | sed 's/ $/",/' | sed '1 s/^/{/' | sed '$ s/,$/}/') + RESPONSE_HEADER=$(echo "$header" "{ \"http_version\": \"${RESPONSE[0]}\", + \"http_status\": \"${RESPONSE[1]}\", + \"http_message\": \"${RESPONSE[@]:2}\", + \"http_response\": \"${RESPONSE[@]:0}\" }" | jq -c -s add) +} + +## run specific methods +display_results() { + + if [[ $API_ERROR == 1 ]]; then + return + fi + + local res=$(jq -r '.http_status + " " + .http_message ' <<<"$RESPONSE_HEADER") + local status=$(jq -r '.http_status' <<<"$RESPONSE_HEADER") + echo "Response:" + echo "${BOLD}$(color_response $status)$res${RESET}" + if [[ $HEADER_ONLY == 1 ]]; then + echo "HEADER:" + echo "$RESPONSE_HEADER" | jq -C '.' + else + if [[ $SHOW_HEADER == 1 ]]; then + echo "HEADER:" + echo "$RESPONSE_HEADER" | jq -C '.' + fi + if [[ $SILENT == 0 ]]; then + echo "BODY:" + echo "$RESPONSE_BODY" | jq -C '.' + fi + + fi + if [[ $SUPER_SILENT == 0 ]]; then + echo "META:" + echo "$META" | jq -C '.' + fi +} + +api_factory() { + for TEST_CASE in $@; do + API_ERROR=0 + echo "${BOLD}Running Case:${RESET} $TEST_CASE" + echo_v "${BOLD}Description: ${RESET}$(jq -r ".testCases.\"$TEST_CASE\".description" $FILE)" + echo_v "${BOLD}Action: ${RESET}$(jq -r ".testCases.\"$TEST_CASE\".method //\"GET\" | ascii_upcase" $FILE) $(jq -r ".testCases.\"$TEST_CASE\".path" $FILE)" + call_api $TEST_CASE + display_results + echo "" + echo "" + done +} + +test_factory() { + TOTAL_TEST_CASE=0 + TOTAL_FAIL_CASE=0 + ANY_API_ERROR=0 + for TEST_CASE in $@; do + API_ERROR=0 + echo "${BOLD}Testing Case:${RESET} $TEST_CASE" + echo_v "${BOLD}Description: ${RESET}$(jq -r ".testCases.\"$TEST_CASE\".description" $FILE)" + echo_v "${BOLD}Action: ${RESET}$(jq -r ".testCases.\"$TEST_CASE\".method //\"GET\" | ascii_upcase" $FILE) $(jq -r ".testCases.\"$TEST_CASE\".path" $FILE)" + if [[ -z $(jq -r ".testCases.\"$TEST_CASE\".expect? | select(. !=null)" $FILE) ]]; then + tput cuf 2 + echo "No test cases found" + echo "" + echo "" + continue + fi + call_api $TEST_CASE + if [[ $API_ERROR == 1 ]]; then + ANY_API_ERROR=1 + tput cuf 2 + echo -e "${BOLD}${RED}Error running tests after failed api request for '$TEST_CASE' ${RESET}" + echo -e "\n" + continue + fi + + local TEST_SCENARIO=$(jq -r ".testCases.\"$TEST_CASE\".expect.header? | select(. !=null and . != {})" $FILE) + if [[ ! -z $TEST_SCENARIO ]]; then + tput cuf 2 + echo "${UNDERLINE}Checking condition for header${RESET}" + test_runner $TEST_CASE "header" "$RESPONSE_HEADER" + echo "" + echo "" + fi + + TEST_SCENARIO=$(jq -r ".testCases.\"$TEST_CASE\".expect.body? | select(. !=null and . != {})" $FILE) + if [[ ! -z $TEST_SCENARIO ]]; then + tput cuf 2 + echo "${UNDERLINE}Checking condition for body${RESET}" + echo "$RESPONSE_BODY" + test_runner $TEST_CASE "body" "$RESPONSE_BODY" + echo "" + echo "" + fi + + TEST_SCENARIO=$(jq -r ".testCases.\"$TEST_CASE\".expect.external? | select(. !=null and . != \"\")" $FILE) + if [[ ! -z $TEST_SCENARIO ]]; then + tput cuf 2 + echo "${UNDERLINE}Checking condition from external program${RESET}" + external_script "$TEST_SCENARIO" "$TEST_CASE" "$RESPONSE_BODY" "$RESPONSE_HEADER" + TOTAL_TEST_CASE=$((TOTAL_TEST_CASE + 1)) + echo "" + echo "" + fi + + done + echo -e "${BOLD}Total tests:\t$TOTAL_TEST_CASE" + if [[ $(($TOTAL_TEST_CASE - $TOTAL_FAIL_CASE)) != 0 ]]; then + printf $GREEN + fi + echo -e "${BOLD}Total success:\t$(($TOTAL_TEST_CASE - $TOTAL_FAIL_CASE))${RESET}" + + if [[ $TOTAL_FAIL_CASE != 0 ]]; then + printf $RED + else + if [[ $ANY_API_ERROR != 0 ]]; then + echo -e "\n${BOLD}${RED}Some test cases failed to connect to the requested api.${RESET}" + exit 1 + else + echo -e "\n${BOLD}${GREEN}All tests ran successfully!${RESET}" + fi + exit 0 + fi + echo -e "${BOLD}Total failure:\t$TOTAL_FAIL_CASE${RESET}" + echo -e "\n${BOLD}${RED}Tests Failed!${RESET}" + exit 1 + +} + +test_runner() { + for test in ""contains eq path_eq path_contains hasKeys[]""; do + local TEST_SCENARIO=$(jq -c -r ".testCases.\"$1\".expect.$2.$test? | select(. !=null)" $FILE) + if [[ -z $TEST_SCENARIO ]]; then + continue + fi + TOTAL_TEST_CASE=$((TOTAL_TEST_CASE + 1)) + tput cuf 4 + if [[ $test == "contains" ]]; then + echo "Checking contains comparision${RESET}" + contains "$TEST_SCENARIO" "$3" + elif [[ $test == "eq" ]]; then + echo "Checking equality comparision${RESET}" + check_eq "$TEST_SCENARIO" "$3" + elif [[ $test == "path_eq" ]]; then + echo "Checking path equality comparision${RESET}" + path_checker "$TEST_SCENARIO" "$3" + elif [[ $test == "path_contains" ]]; then + echo "Checking path contains comparision${RESET}" + path_checker "$TEST_SCENARIO" "$3" 1 + else + echo "Checking has key comparision${RESET}" + has_key "$TEST_SCENARIO" "$3" + fi + done +} + +external_script() { + $1 "$2" "$3" "$4" + local EXIT_CODE=$? + if [[ $EXIT_CODE == 0 ]]; then + tput cuf 4 + echo "${GREEN}${BOLD}Check Passed${RESET}" + else + tput cuf 4 + echo "${RED}${BOLD}Check Failed${RESET}" + TOTAL_FAIL_CASE=$((TOTAL_FAIL_CASE + 1)) + fi +} + +contains() { + tput cuf 6 + local check=$(jq -c --argjson a "$1" --argjson b "$2" -n '$a | select(. != null) | $b | contains($a)') + if [[ $check == "true" ]]; then + echo "${GREEN}${BOLD}Check Passed${RESET}" + else + echo "${RED}${BOLD}Check Failed${RESET}" + TOTAL_FAIL_CASE=$((TOTAL_FAIL_CASE + 1)) + echo "EXPECTED:" + echo "${GREEN}$1${RESET}" + echo "GOT:" + echo "${RED}$2${RESET}" + echo "" + fi +} + +has_key() { + # local paths=$(jq -r 'def path2text($value): + # def tos: if type == "number" then . else "\"\(tojson)\"" end; + # reduce .[] as $segment (""; . + # + ($segment + # | if type == "string" then "." + . else "[\(.)]" end)); + # paths(scalars) as $p + # | getpath($p) as $v + # | $p | path2text($v)' <<<"$2") + local paths=$(jq -r 'path(..)|[.[]|tostring]|join(".")' <<<"$2") + tput cuf 6 + for path in $1; do + local FOUND=0 + for data_path in $paths; do + if [[ "$path" == "$data_path" ]]; then + FOUND=1 + break + fi + done + if [[ $FOUND == 0 ]]; then + echo "${RED}${BOLD}Check Failed${RESET}" + TOTAL_FAIL_CASE=$((TOTAL_FAIL_CASE + 1)) + echo "CANNOT FIND KEY:" + echo "${RED}$path${RESET}" + echo "" + return + fi + done + echo "${GREEN}${BOLD}Check Passed${RESET}" +} + +check_eq() { + tput cuf 6 + local type=$(jq -r -c --argjson a "$1" -n '$a|type' 2>/dev/null) + local check + if [[ $type == "object" || $type == "array" ]]; then + check=$(jq -c --argjson a "$1" --argjson b "$2" -n 'def post_recurse(f): def r: (f | select(. != null) | r), .; r; def post_recurse: post_recurse(.[]?); ($a | (post_recurse | arrays) |= sort) as $a | ($b | (post_recurse | arrays) |= sort) as $b | $a == $b') + elif [[ $type == "number" || $type == "boolean" || $type == "null" || $type == "string" ]]; then + check=$(jq -c --argjson a "$1" --argjson b "$2" -n '$a == $b') + else + if [[ $1 == $2 ]]; then + check="true" + else + check="false" + fi + fi + if [[ $check == "true" ]]; then + echo "${GREEN}${BOLD}Check Passed${RESET}" + else + tput cuf 2 + echo "${RED}${BOLD}Check Failed${RESET}" + TOTAL_FAIL_CASE=$((TOTAL_FAIL_CASE + 1)) + echo "EXPECTED:" + echo "${GREEN}$1${RESET}" + echo "GOT:" + echo "${RED}$2${RESET}" + echo "" + fi +} + +path_checker() { + local keys=$(jq -c -r --argjson a "$1" -n '$a | keys[]') + if [[ -z "$keys" ]]; then + return + fi + for key in $keys; do + tput cuf 6 + local value=$(jq -c -r --argjson a "$1" -n "\$a | .\"$key\"") + echo "When path is '$key'" + local compare_value=$(jq -c -r --argjson a "$2" -n "\$a | try .$key catch \"OBJECT_FETCH_ERROR_JQ_API_TEST\"" 2>/dev/null) + if [[ -z "$compare_value" ]]; then + tput cuf 8 + echo "${RED}${BOLD}Check Failed${RESET}" + TOTAL_FAIL_CASE=$((TOTAL_FAIL_CASE + 1)) + tput cuf 2 + echo "INVALID PATH SYNTAX: ${RED}data[0]target_id${RESET}" + return + fi + tput cuf 2 + if [[ $3 == 1 ]]; then + contains "$value" "$compare_value" + else + check_eq "$value" "$compare_value" + fi + done +} + +# run command +run() { + for arg in "$@"; do + case $arg in + -i | --include) + SHOW_HEADER=1 + shift + ;; + -I | --header-only) + HEADER_ONLY=1 + shift + ;; + -s | --silent) + SILENT=1 + shift + ;; + -S | --super-silent) + SILENT=1 + SUPER_SILENT=1 + shift + ;; + -h | --help) + usage run + exit + ;; + esac + done + + case $1 in + all) + api_factory "$(jq -r '.testCases | keys[]' $FILE)" + ;; + '') usage run ;; + *) + api_factory $@ + ;; + esac +} + +# test command +test() { + for arg in "$@"; do + case $arg in + -h | --help) + usage test + exit + ;; + esac + done + + case $1 in + all) + test_factory "$(jq -r '.testCases | keys[]' $FILE)" + ;; + '') + usage test + ;; + *) + test_factory $@ + ;; + esac +} + +# describe command +describe() { + for arg in "$@"; do + case $arg in + -h | --help) + usage describe + exit + ;; + esac + done + + case $1 in + '') + echo -e "S.N.\tTest case" + jq -r '.testCases | keys[]' $FILE | awk '{print NR "\t" $0}' + ;; + *) + jq -r ".testCases | .$1 | .$2?" $FILE + ;; + esac +} + +# INIT COMMANDS AND CHECKS +for arg in "$@"; do + case $arg in + run | test | describe) + ACTION="$1" + shift + break + ;; + -f | --file) + FILE="$2" + shift + ;; + -h | --help) + usage + exit + ;; + --version) + echo "api-test version $VERSION" + exit + ;; + -v | --verbose) + VERBOSE=1 + shift + ;; + *) + shift + ;; + esac +done + +# Check for dependency programs +command -v curl >/dev/null 2>&1 || { + echo >&2 "This program requires 'curl' to run. Please install 'curl'" + exit 1 +} +command -v jq >/dev/null 2>&1 || { + echo >&2 "This program requires 'jq' to run. Please install 'jq'" + exit 1 +} + +if [ ! -f "$FILE" ]; then + DEFAULT_FILE=("test.json api-test.json template.json") + FOUND_FILE=0 + for default in $DEFAULT_FILE; do + if [ -f "$default" ]; then + FOUND_FILE=1 + FILE=$default + break + fi + done + if [[ $FOUND_FILE == 0 ]]; then + echo "Please provide an existing file." + exit 1 + fi +fi + +jq empty $FILE + +if [ $? -ne 0 ]; then + exit 1 +fi + +# Check if url is present +URL=$(jq -r '.url | select( . != null)' $FILE) +if [[ -z $URL ]]; then + echo "'url' is a required field in base object of a test file and must be a string." + exit 1 +fi + +COMMON_HEADER=$(cat $FILE | jq -r -c ". | .header | if . != null then . else {} end | to_entries | map(\"\(.key): \(.value|tostring)\") | join(\"\n\") | if ( . | length) != 0 then \"-H\" + . else \"-H \" end") +# Check if test cases is present +if [[ -z $(jq -r '.testCases | select(. != null and . != {})' $FILE) ]]; then + echo "'testCases' is a required field in base object of a test file and must have atleast one test case." + exit 1 +fi + +case $ACTION in +run) + run $@ + ;; +test) test $@ ;; +describe) describe $@ ;; +*) + usage + ;; +esac \ No newline at end of file diff --git a/controllers/unlock.go b/controllers/unlock.go index 00de775..71531b7 100644 --- a/controllers/unlock.go +++ b/controllers/unlock.go @@ -22,7 +22,7 @@ func Unlock(c *gin.Context) { c.JSON(http.StatusBadRequest, gin.H{"error": err.Error()}) return } - log.Printf("Unlock received JSON input '%v'\n", input) + log.Println("Unlock received JSON input") // check that the key is 32 bytes long if len(input.SecretKey) != 32 { diff --git a/models/secret.go b/models/secret.go index 7efd4d4..b4685be 100644 --- a/models/secret.go +++ b/models/secret.go @@ -49,7 +49,7 @@ func GetSecrets(s *Secret, adminRole bool) ([]Secret, error) { var rows *sqlx.Rows var secretResults []Secret - log.Printf("GetSecret querying values '%v' with admin role '%v'\n", s, adminRole) + log.Printf("GetSecrets querying values '%v' with admin role '%v'\n", s, adminRole) // Admin roles should be able to access all secrets so don't do any filter based on RoleId if adminRole { @@ -116,7 +116,9 @@ func GetSecrets(s *Secret, adminRole bool) ([]Secret, error) { // Decrypt the secret _, err = r.DecryptSecret() if err != nil { - log.Printf("GetSecret unable to decrypt stored secret '%v', skipping result.\n", r.Secret) + //log.Printf("GetSecret unable to decrypt stored secret '%v' : '%s'\n", r.Secret, err) + log.Printf("GetSecret unable to decrypt stored secret : '%s'\n", err) + return secretResults, err } else { secretResults = append(secretResults, r) } @@ -153,6 +155,28 @@ func (s *Secret) UpdateSecret() (*Secret, error) { return s, nil } +// startCipher does the initial setup of the AES256 GCM mode cipher +func startCipher() (cipher.AEAD, error) { + key, err := ProvideKey() + if err != nil { + return nil, err + } + + block, err := aes.NewCipher(key) + if err != nil { + log.Printf("startCipher NewCipher error '%s'\n", err) + return nil, err + } + + aesgcm, err := cipher.NewGCM(block) + if err != nil { + log.Printf("startCipher NewGCM error '%s'\n", err) + return nil, err + } + + return aesgcm, nil +} + func (s *Secret) EncryptSecret() (*Secret, error) { //keyString := os.Getenv("SECRETS_KEY") @@ -161,25 +185,34 @@ func (s *Secret) EncryptSecret() (*Secret, error) { // The key argument should be the AES key, either 16 or 32 bytes // to select AES-128 or AES-256. //key := []byte(keyString) - key, err := ProvideKey() - if err != nil { - return s, err - } + /* + key, err := ProvideKey() + if err != nil { + return s, err + } + */ plaintext := []byte(s.Secret) - log.Printf("EncryptSecret applying key '%v' of length '%d' to plaintext secret '%s'\n", key, len(key), s.Secret) - // TODO : move block and aesgcm generation to separate function since the identical code is used for encrypt and decrypt - block, err := aes.NewCipher(key) - if err != nil { - log.Printf("EncryptSecret NewCipher error '%s'\n", err) - return s, err - } + /* + log.Printf("EncryptSecret applying key '%v' of length '%d' to plaintext secret '%s'\n", key, len(key), s.Secret) + block, err := aes.NewCipher(key) + if err != nil { + log.Printf("EncryptSecret NewCipher error '%s'\n", err) + return s, err + } - aesgcm, err := cipher.NewGCM(block) + aesgcm, err := cipher.NewGCM(block) + if err != nil { + log.Printf("EncryptSecret NewGCM error '%s'\n", err) + return s, err + } + */ + + aesgcm, err := startCipher() if err != nil { - log.Printf("EncryptSecret NewGCM error '%s'\n", err) + log.Printf("EncryptSecret error commencing GCM cipher '%s'\n", err) return s, err } @@ -189,15 +222,15 @@ func (s *Secret) EncryptSecret() (*Secret, error) { log.Printf("EncryptSecret nonce generation error '%s'\n", err) return s, err } - log.Printf("EncryptSecret random nonce value is '%x'\n", nonce) + //log.Printf("EncryptSecret random nonce value is '%x'\n", nonce) ciphertext := aesgcm.Seal(nil, nonce, plaintext, nil) - log.Printf("EncryptSecret generated ciphertext '%x''\n", ciphertext) + //log.Printf("EncryptSecret generated ciphertext '%x''\n", ciphertext) // Create a new slice to store nonce at the start and then the resulting ciphertext // Nonce is always 12 bytes combinedText := append(nonce, ciphertext...) - log.Printf("EncryptSecret combined secret value is now '%x'\n", combinedText) + //log.Printf("EncryptSecret combined secret value is now '%x'\n", combinedText) // Store the value back into the struct ready for database operations s.Secret = hex.EncodeToString(combinedText) @@ -214,10 +247,12 @@ func (s *Secret) DecryptSecret() (*Secret, error) { //keyString := secretKey //key := []byte(keyString) - key, err := ProvideKey() - if err != nil { - return s, err - } + /* + key, err := ProvideKey() + if err != nil { + return s, err + } + */ if len(s.Secret) < nonceSize { log.Printf("DecryptSecret ciphertext is too short to decrypt\n") @@ -230,23 +265,31 @@ func (s *Secret) DecryptSecret() (*Secret, error) { return s, err } - log.Printf("DecryptSecret processing secret '%x'\n", crypted) + //log.Printf("DecryptSecret processing secret '%x'\n", crypted) // The nonce is the first 12 bytes from the ciphertext nonce := crypted[:nonceSize] ciphertext := crypted[nonceSize:] - log.Printf("DecryptSecret applying key '%v' and nonce '%x' to ciphertext '%x'\n", key, nonce, ciphertext) + /* + log.Printf("DecryptSecret applying key '%v' and nonce '%x' to ciphertext '%x'\n", key, nonce, ciphertext) - block, err := aes.NewCipher(key) - if err != nil { - log.Printf("DecryptSecret NewCipher error '%s'\n", err) - return s, err - } + block, err := aes.NewCipher(key) + if err != nil { + log.Printf("DecryptSecret NewCipher error '%s'\n", err) + return s, err + } - aesgcm, err := cipher.NewGCM(block) + aesgcm, err := cipher.NewGCM(block) + if err != nil { + log.Printf("DecryptSecret NewGCM error '%s'\n", err) + return s, err + } + */ + + aesgcm, err := startCipher() if err != nil { - log.Printf("DecryptSecret NewGCM error '%s'\n", err) + log.Printf("DecryptSecret error commencing GCM cipher '%s'\n", err) return s, err } @@ -256,7 +299,7 @@ func (s *Secret) DecryptSecret() (*Secret, error) { return s, err } - log.Printf("DecryptSecret plaintext is '%s'\n", plaintext) + //log.Printf("DecryptSecret plaintext is '%s'\n", plaintext) s.Secret = string(plaintext) return s, nil