bruncsak / ght-acme.sh

Get publicly trusted certificate via ACME protocol from LetsEncrypt or from BuyPass
GNU General Public License v2.0
41 stars 9 forks source link

Replace the functionality of xxd #4

Open SDuesterhaupt opened 4 years ago

SDuesterhaupt commented 4 years ago

xxd is hard to get in distributions like CentOS.

Maybe it's better to include an alternative functionality like this:

hex2string() {
  MyRun=true
  while $MyRun; do
    if [ ! -z "$1" ]; then
      MyPart=$1
      MyRun=false
    else
      read MyPart
      MyTest=$?
      if [ $MyTest -ne 0 ]; then
        MyRun=false
      fi
    fi
    I=0
    while [ $I -lt ${#MyPart} ];
    do
      echo -en "\x"${MyPart:$I:2}
      let "I += 2"
    done
  done
}

The usage is for example in the function key_get_modulus():

#sed -e 's/^Modulus=//' < "$OPENSSL_OUT" \
# | xxd -r -p \
# | base64url
sed -e 's/^Modulus=//' < "$OPENSSL_OUT" \
 | hex2string \
 | base64url
bruncsak commented 4 years ago

It is very easy to get xxd for CentOS, just do as root: yum install vim-common

On the other hand I support your idea to replace xxd with standard shell code sequence.

The problem with your code that it runs only on recent bash. It does not run on ksh, not even talking about xpg4 or svr4 standard only shells. I already made effort to backport my code to support Tru64 UNIX and Solaris.

SDuesterhaupt commented 4 years ago

27 M vim-common installation size for using only this function? This was the reason to think about an alternative.

You are right, the code is developed and tested for the bash shell. I concentrate on RedHat/CentOS.

And this code is an example. The development state is from 2016. In the meanwhile I develop shell code under consideration of POSIX (mostly, sometimes it's a hard business).

What I can see immediately is the command let "I += 2" which is definitely not POSIX compatible. Today I would use such a construction:

I="$((I+2))"

I will revise this part.

bruncsak commented 4 years ago
SDuesterhaupt commented 4 years ago
  • the POSIX shell on Tru64 UNIX fails on ${MyPart:$I:2}. That looks like a double shell variable expansion.

It's a command construction to expand a substring of a given parameter: ${parameter:offset:length}.

The parameter is in our case 1 because we have only one parameter ($1).

To substitute this under consideration of POSIX we can maybe use a construction like this:

echo $1 | sed 's/^.\{'$I'\}\(.\{2\}\).*/\1/'

And within the test function __hex2string2 ():

function __hex2string2 () {
  I=0
  while [ $I -lt ${#1} ];
  do
    echo -en "\x"$(echo $1 | sed 's/^.\{'$I'\}\(.\{2\}\).*/\1/')
    I="$((I+2))"
  done
}

The call sequence is:

__hex2string2 "48616c6c6f2057656c74210a"

For sure it's not the be-all and end-all. In this example for example the command construction takes always the whole length of the parameter $1.

Further ideas?

bruncsak commented 4 years ago

That is very good. I think the other problem is harder. Do we have to do some hexadecimal -> octal math?

bruncsak commented 4 years ago

I committed the fix: https://github.com/bruncsak/ght-acme.sh/commit/1f408c52f839cd2a22f9cfccfa78f43bf1944f1c

SDuesterhaupt commented 4 years ago
  • the built in echo of the ksh does not know the \x<hexdigit><hexdigit> escape sequence.

I just love scripting in Linux... :heart_eyes: Two alternatives which seem to solve this issue and run also in ksh:

#!/bin/ksh

__hex2string2 () {
  I=0
  while [ "$I" -lt "${#1}" ];
  do
    #echo -en "\x"$(echo $1 | sed 's/^.\{'$I'\}\(.\{2\}\).*/\1/')
    #printf '\x'$(echo $1 | sed 's/^.\{'$I'\}\(.\{2\}\).*/\1/')

    echo -en "$(printf '\x'$(echo $1 | sed 's/^.\{'$I'\}\(.\{2\}\).*/\1/'))"

    I="$((I+2))"
  done
}

__hex2string3 () {
  I=0
  while [ "$I" -lt "${#1}" ];
  do
    #echo -en "\x"$(echo $1 | sed 's/^.\{'$I'\}\(.\{2\}\).*/\1/')

    MyHEX=$(echo $1 | sed 's/^.\{'$I'\}\(.\{2\}\).*/\1/')
    #echo "$MyHEX"
    MyDECIMAL="$((16#$MyHEX))"
    typeset -i8 MyOCT=MyDECIMAL               # typeset adds the base '8#' 
    #echo "$MyOCT"
    MyOCT2=$(echo "$MyOCT" | sed 's/8\#//g')  # remove the base '8#'
    #echo "$MyOCT2"
    MyCHAR=$(echo "\0${MyOCT2}")
    echo -en "${MyCHAR}"

    I="$((I+2))"
  done
}

__hex2string2 "48616c6c6f2057656c74210a"

echo -e "\n"

__hex2string3 "48616c6c6f2057656c74210a"

exit 0