Using string parameter in bash script failt

113 Views Asked by At

I need to create a few certificates and wanted to write a small bash script for this.

First of all, I don't have much experience with creating my own bash scripts.

I wanted to pass the most important values like computer name and password as parameters. Unfortunately I get the error:

keytool error :java.io.IoException:Incorrect AVA format

The error indicates that the strings in the commands are not interpreted correctly. I think the problem is that I am not working properly with the strings, but I don't understand exactly what is wrong.

If I enter the command like this in the terminal it works fine

#!/bin/bash

echo "$1" # servername
echo "$2" # domain
echo "$3" # password
echo

keytool -noprompt -keystore $1.$2.truststore.jks -alias CARoot -import -file ca.cert -storetype jks -storepass $3 -keypass $3

keytool -genkey -noprompt -keyalg RSA -storetype pkcs12 -alias $1.$2 -dname $1'.'$2',O=COMPANY,OU=COMPANY,L=NY,ST=NY,C=us' \
      -ext 'SAN=DNS:example1.com,DNS:example2.com'
      -keystore $1.$2'.keystore2.jks' -storepass $3 -keypass $3

Can you tell me what I am doing wrong?

2

There are 2 best solutions below

1
Ed Morton On BEST ANSWER

Try this, using correct quoting, correct escaping of end of line, and adding the missing CN= to the -dname option string.:

keytool -genkey -noprompt -keyalg RSA -storetype pkcs12 -alias "$1.$2" \
      -dname "CN=$1.$2,O=COMPANY,OU=COMPANY,L=NY,ST=NY,C=us" \
      -ext 'SAN=DNS:example1.com,DNS:example2.com' \
      -keystore "$1.$2.keystore2.jks" -storepass "$3" -keypass "$3"

Investigation details and observations below...

You tell us in a comment that this works:

server_name="$1"
domain="$2"
password="$3"

keytool -noprompt -keystore "$server_name.$domain.truststore.jks" -alias CARoot -import -file ca.cert -storetype jks -storepass "$password" -keypass "$password"

and you tell us in another comment that this works:

keytool -genkey -noprompt \
-keyalg RSA \
-storetype pkcs12 \
-alias server.example.com \
-dname 'CN=server.example.com,O=COMPANY,OU=COMPANY,L=NY,ST=NY,C=US' \
-ext "SAN=DNS:example.com, DNS:example2.com" \
-keystore server.example.com.keystore.jks \
-storepass 'passwort!#' \
-keypass 'passwort!#'

If that 2nd script above with hard-coded values works then this one using variables for the options we'll later populate from script arguments must also work:

#!/usr/bin/env bash

the_alias='server.example.com'
the_dname='CN=server.example.com,O=COMPANY,OU=COMPANY,L=NY,ST=NY,C=US'
the_keystore='server.example.com.keystore.jks'
the_pass='passwort!#'

keytool -genkey -noprompt \
-keyalg RSA \
-storetype pkcs12 \
-alias "$the_alias" \
-dname "$the_dname" \
-ext 'SAN=DNS:example.com, DNS:example2.com' \
-keystore "$the_keystore" \
-storepass "$the_pass" \
-keypass "$the_pass"

If that works, then we just need to map the values being used as options in the command that does not work (copied from your question and laid out one per line for comparison with the other scripts I'm using and with the missing escape fixed):

keytool -genkey -noprompt \
-keyalg RSA \
-storetype pkcs12 \
-alias $1.$2 \
-dname $1'.'$2',O=COMPANY,OU=COMPANY,L=NY,ST=NY,C=us' \
-ext 'SAN=DNS:example1.com,DNS:example2.com' \
-keystore $1.$2'.keystore2.jks' \
-storepass $3 \
-keypass $3

to populate the variables we introduced from the arguments passed to your script instead of hard-coding them and then this must work:

#!/usr/bin/env bash

the_alias="$1.$2"
the_dname="CN=${the_alias},O=COMPANY,OU=COMPANY,L=NY,ST=NY,C=us"
the_keystore="${the_alias}.keystore.jks"
the_pass="$3"

keytool -genkey -noprompt \
-keyalg RSA \
-storetype pkcs12 \
-alias "$the_alias" \
-dname "$the_dname" \
-ext 'SAN=DNS:example.com, DNS:example2.com' \
-keystore "$the_keystore" \
-storepass "$the_pass" \
-keypass "$the_pass"

where you call the above as:

./the_script 'server' 'example.com' 'passwort!#'

So - does that work or not? If not, which of the above 2 scripts I provided fail?

While doing that coding I noticed that, in addition to the missing quotes and missing backslash at the end of the -ext line in the failing script:

  • The version of the code you say worked uses keystore.jks while the version you say does not work uses keystore2.jks (note the 2)
  • Similarly for SAN=DNS:example.com vs SAN=DNS:example1.com (note the 1).
  • The blank character after , is only present in the working -ext option string.
  • The -dname option in your working script starts with CN= while in the failing one it does not.

Are any of those a problem?

7
Vinith_jk_bro On

It's the way you're handling spaces and concatenating strings. When passing parameters in a script, u need to properly quote variables to handle cases where values contain spaces.

Try this modified version of your script:

#!/bin/bash
server_name="$1"
domain="$2"
password="$3"
echo "$server_name"
echo "$domain"
echo "$password"
keytool -noprompt -keystore "$server_name.$domain.truststore.jks" -alias CARoot -import -file ca.cert -storetype jks -storepass "$password" -keypass "$password"
keytool -genkey -noprompt -keyalg RSA -storetype pkcs12 -alias "$server_name.$domain" -dname "$server_name.$domain,O=COMPANY,OU=COMPANY,L=NY,ST=NY,C=us" \
      -ext "SAN=DNS:example1.com,DNS:example2.com" -keystore "$server_name.$domain.keystore2.jks" -storepass "$password" -keypass "$password"

This script properly quotes variables and ensures that filenames and values with spaces are handled correctly. Do try it out!