#!/bin/bash - #=============================================================================== # # FILE: genSSLcsr.sh # # USAGE: ./genSSLcsr.sh [options] # # DESCRIPTION: ++++version 1.0.2 # Fixed few bugs from previous script # +Removing passphrase after CSR generation # Extended use of functions # Checks for valid common name # ++++1.0.3 # Fixed line breaks # Work directory to be created at the start # Used getopts for better code arrangements # ++++1.0.4 # Added mail feature (experimental at this time and needs # a mail server running locally.) # Added domain input and certificate subject inputs # # OPTIONS: --- # REQUIREMENTS: openssl, mailx # BUGS: --- # NOTES: --- # AUTHOR: Abhishek Tamrakar (), [email protected] # ORGANIZATION: Self # CREATED: 6/24/2016 # REVISION: 4 # COPYRIGHT AND # LICENSE: Copyright (C) 2016 Abhishek Tamrakar # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at # # http://www.apache.org/licenses/LICENSE-2.0 # # Unless required by applicable law or agreed to in writing, software # distributed under the License is distributed on an "AS IS" BASIS, # WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. # See the License for the specific language governing permissions and # limitations under the License. #=============================================================================== #variables ges here #set basename to scriptname SCRIPT=${0##*/} #set flags TFOUND=0 CFOUND=0 MFOUND=0 XFOUND=0 SFOUND=0 logdir=/var/log # edit these below values to replace with yours homedir='' yourdomain='' country=IN state=Maharashtra locality=Pune organization="your_organization" organizationalunit="your_organizational_unit" email=your_email@your_domain password=your_ssl_password # OS is declared and will be used in its next version OS=$(egrep -io 'Redhat|centos|fedora|ubuntu' /etc/issue) ### function declarations ### info() { printf '\n%s\t%s\t' "INFO" "$@" } #exit on error with a custom error message #the extra function was removed and replaced withonly one. #using FAILED\n\e is a way but not necessarily required. # fatal() { printf '\n%s\t%s\n' "ERROR" "$@" exit 1 } checkperms() { if [[ -z ${homedir} ]]; then homedir=$(pwd) fi if [[ -w ${homedir} ]]; then info "Permissions acquired for ${SCRIPT} on ${homedir}." else fatal "InSufficient permissions to run the ${SCRIPT}." fi } checkDomain() { info "Initializing Domain ${cn} check ? " if [[ ! -z ${yourdomain} ]]; then workdir=${homedir}/${yourdomain} echo -e "${cn}"|grep -E -i -q "${yourdomain}$" && echo -n "[OK]" || fatal "InValid domain in ${cn}" else workdir=${homedir}/${cn#*.} echo -n "[NULL]" info "WARNING: No domain declared to check." confirmUserAction fi } # end function checkDomain usage() { cat << EOF Usage: $SCRIPT [options] -[cdmshx] [-c (common name)] [-d (domain name)] [-s (SSL certificate subject)] [-p (password)] [-m (email address)] *(Experimental) [-r (remove pasphrase) default:true] [-h (help)] [-x (optional)] [OPTIONS] -c| Sets the value for common name. A valid common name is something that ends with 'xyz.com' -d| Sets the domain name. -s| Sets the subject to be applied to the certificates. '/C=country/ST=state/L=locality/O=organization/OU=organizationalunit/emailAddress=email' -p| Sets the password for private key. -r| Sets the value of remove passphrase. true:[default] passphrase will be removed from key. false: passphrase will not be removed and key wont get printed. -m| Sets the mailing capability to the script. (Experimental at this time and requires a lot of work) -x| Creates the certificate request and key but do not print on screen. To be used when script is used just to create the key and CSR with no need + to generate the certficate on the go. -h| Displays the usage. No further functions are performed. Example: $SCRIPT -c mywebsite.xyz.com -m [email protected] EOF exit 1 } # end usage confirmUserAction() { while true; do read -p "Do you wish to continue? ans: " yn case $yn in [Yy]* ) info "Initiating the process"; break;; [Nn]* ) exit 1;; * ) info "Please answer yes or no.";; esac done } # end function confirmUserAction parseSubject() { local subject="$1" parsedsubject=$(echo $subject|sed 's/\// /g;s/^ //g') for i in ${parsedsubject}; do case ${i%%=*} in 'C' ) country=${i##*=} ;; 'ST' ) state=${i##*=} ;; 'L' ) locality=${i##*=} ;; 'O' ) organization=${i##*=} ;; 'OU' ) organizationalunit=${i##*=} ;; 'emailAddress' ) email=${i##*=} ;; esac done } sendMail() { mailcmd=$(which mailx) if [[ x"$mailcmd" = "x" ]]; then fatal "Cannot send email! please install mailutils for linux" else echo "SSL CSR attached." | $mailcmd -s "SSL certificate request" \ -t $email $ccemail -A ${workdir}/${cn}.csr \ && info "mail sent" \ || fatal "error in sending mail." fi } genCSRfile() { info "Creating signed key request for ${cn}" #Generate a key openssl genrsa -des3 -passout pass:$password -out ${workdir}/${cn}.key 4096 -noout 2>/dev/null && echo -n "[DONE]" || fatal "unable to generate key" #Create the request info "Creating Certificate request for ${cn}" openssl req -new -key ${workdir}/${cn}.key -passin pass:$password -sha1 -nodes \ -subj "/C=$country/ST=$state/L=$locality/O=$organization/OU=$organizationalunit/CN=$cn/emailAddress=$email" \ -out ${workdir}/${cn}.csr && echo -n "[DONE]" || fatal "unable to create request" if [[ "${REMOVEPASSPHRASE:-true}" = 'true' ]]; then #statements #Remove passphrase from the key. Comment the line out to keep the passphrase info "Removing passphrase from ${cn}.key" openssl rsa -in ${workdir}/${cn}.key \ -passin pass:$password \ -out ${workdir}/${cn}.insecure 2>/dev/null \ && echo -n "[DONE]" || fatal "unable to remove passphrase" #swap the filenames info "Swapping the ${cn}.key to secure" mv ${workdir}/${cn}.key ${workdir}/${cn}.secure \ && echo -n "[DONE]" || fatal "unable to perfom move" info "Swapping insecure key to ${cn}.key" mv ${workdir}/${cn}.insecure ${workdir}/${cn}.key \ && echo -n "[DONE]" || fatal "unable to perform move" else info "Flag '-r' is set, passphrase will not be removed." fi } printCSR() { if [[ -e ${workdir}/${cn}.csr ]] && [[ -e ${workdir}/${cn}.key ]] then echo -e "\n\n----------------------------CSR-----------------------------" cat ${workdir}/${cn}.csr echo -e "\n----------------------------KEY-----------------------------" cat ${workdir}/${cn}.key echo -e "------------------------------------------------------------\n" else fatal "CSR or KEY generation failed !!" fi } ### END Functions ### #Check the number of arguments. If none are passed, print help and exit. NUMARGS=$# if [ $NUMARGS -eq 0 ]; then fatal "$NUMARGS Arguments provided !!!! See usage with '-h'" fi #Organisational details while getopts ":c:d:s:m:p:rhx" atype do case $atype in c ) CFOUND=1 cn="$OPTARG" ;; d ) yourdomain="$OPTARG" ;; s ) SFOUND=1 subj="$OPTARG" ;; p ) password="$OPTARG" ;; r ) REMOVEPASSPHRASE='false' ;; m ) MFOUND=1 ccemail="$OPTARG" ;; x ) XFOUND=1 ;; h ) usage ;; \? ) usage ;; : ) fatal "Argument required !!! see \'-h\' for help" ;; esac done shift $(($OPTIND - 1)) #### END CASE #### START MAIN #### if [ $CFOUND -eq 1 ] then # take current dir as homedir by default. checkperms ${homedir} checkDomain if [[ ! -d ${workdir} ]] then mkdir ${workdir:-${cn#*.}} 2>/dev/null && info "${workdir} created." else info "${workdir} exists." fi # end workdir check parseSubject "$subj" genCSRfile if [ $XFOUND -eq 0 ] then sleep 2 printCSR fi # end x check if [[ $MFOUND -eq 1 ]]; then sendMail fi else fatal "Nothing to do!" fi # end common name check ##### END MAIN #####