mirror of
				https://github.com/hiskang/acme.sh
				synced 2025-10-31 02:17:18 +00:00 
			
		
		
		
	1.1.9, do not register account key each time. compare the account key hash.
This commit is contained in:
		
							parent
							
								
									bac3b6b08d
								
							
						
					
					
						commit
						166096dc12
					
				
							
								
								
									
										176
									
								
								le.sh
									
									
									
									
									
								
							
							
						
						
									
										176
									
								
								le.sh
									
									
									
									
									
								
							| @ -1,5 +1,5 @@ | |||||||
| #!/usr/bin/env bash | #!/usr/bin/env bash | ||||||
| VER=1.1.8 | VER=1.1.9 | ||||||
| PROJECT="https://github.com/Neilpang/le" | PROJECT="https://github.com/Neilpang/le" | ||||||
| 
 | 
 | ||||||
| DEFAULT_CA="https://acme-v01.api.letsencrypt.org" | DEFAULT_CA="https://acme-v01.api.letsencrypt.org" | ||||||
| @ -202,7 +202,7 @@ createCSR() { | |||||||
| 
 | 
 | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
| _b64() { | _urlencode() { | ||||||
|   __n=$(cat) |   __n=$(cat) | ||||||
|   echo $__n | tr '/+' '_-' | tr -d '= ' |   echo $__n | tr '/+' '_-' | tr -d '= ' | ||||||
| } | } | ||||||
| @ -232,21 +232,104 @@ _stat() { | |||||||
|   fi |   fi | ||||||
| } | } | ||||||
| 
 | 
 | ||||||
|  | #keyfile | ||||||
|  | _calcjwk() { | ||||||
|  |   keyfile="$1" | ||||||
|  |   if [ -z "$keyfile" ] ; then | ||||||
|  |     _err "Usage: _calcjwk keyfile" | ||||||
|  |     return 1 | ||||||
|  |   fi | ||||||
|  |   EC_SIGN="" | ||||||
|  |   if grep "BEGIN RSA PRIVATE KEY" "$keyfile" > /dev/null 2>&1 ; then | ||||||
|  |     _debug "RSA key" | ||||||
|  |     pub_exp=$(openssl rsa -in $keyfile  -noout -text | grep "^publicExponent:"| cut -d '(' -f 2 | cut -d 'x' -f 2 | cut -d ')' -f 1) | ||||||
|  |     if [ "${#pub_exp}" == "5" ] ; then | ||||||
|  |       pub_exp=0$pub_exp | ||||||
|  |     fi | ||||||
|  |     _debug pub_exp "$pub_exp" | ||||||
|  |      | ||||||
|  |     e=$(echo $pub_exp | _h2b | _base64) | ||||||
|  |     _debug e "$e" | ||||||
|  |      | ||||||
|  |     modulus=$(openssl rsa -in $keyfile -modulus -noout | cut -d '=' -f 2 ) | ||||||
|  |     n=$(echo $modulus| _h2b | _base64 | _urlencode ) | ||||||
|  |     jwk='{"e": "'$e'", "kty": "RSA", "n": "'$n'"}' | ||||||
|  |     _debug jwk "$jwk" | ||||||
|  |      | ||||||
|  |     HEADER='{"alg": "RS256", "jwk": '$jwk'}' | ||||||
|  |     HEADERPLACE='{"nonce": "NONCE", "alg": "RS256", "jwk": '$jwk'}' | ||||||
|  |   elif grep "BEGIN EC PRIVATE KEY" "$keyfile" > /dev/null 2>&1 ; then | ||||||
|  |     _debug "EC key" | ||||||
|  |     EC_SIGN="1" | ||||||
|  |     crv="$(openssl ec  -in $keyfile  -noout -text 2>/dev/null | grep "^NIST CURVE:" | cut -d ":" -f 2 | tr -d " \r\n")" | ||||||
|  |     _debug crv $crv | ||||||
|  |      | ||||||
|  |     pubi="$(openssl ec  -in $keyfile  -noout -text 2>/dev/null | grep -n pub: | cut -d : -f 1)" | ||||||
|  |     _debug pubi $pubi | ||||||
|  |     let "pubi=pubi+1" | ||||||
|  |      | ||||||
|  |     pubj="$(openssl ec  -in $keyfile  -noout -text 2>/dev/null | grep -n "ASN1 OID:"  | cut -d : -f 1)" | ||||||
|  |     _debug pubj $pubj | ||||||
|  |     let "pubj=pubj-1" | ||||||
|  |      | ||||||
|  |     pubtext="$(openssl ec  -in $keyfile  -noout -text 2>/dev/null | sed  -n "$pubi,${pubj}p" | tr -d " \n\r")" | ||||||
|  |     _debug pubtext "$pubtext" | ||||||
|  |      | ||||||
|  |     xlen="$(printf "$pubtext" | tr -d ':' | wc -c)" | ||||||
|  |     let "xlen=xlen/4" | ||||||
|  |     _debug xlen $xlen | ||||||
|  |      | ||||||
|  |     let "xend=xlen+1" | ||||||
|  |     x="$(printf $pubtext | cut -d : -f 2-$xend)" | ||||||
|  |     _debug x $x | ||||||
|  |      | ||||||
|  |     x64="$(printf $x | tr -d : | _h2b | _base64 | _urlencode)" | ||||||
|  |     _debug x64 $x64 | ||||||
|  |      | ||||||
|  |     let "xend+=1" | ||||||
|  |     y="$(printf $pubtext | cut -d : -f $xend-10000)" | ||||||
|  |     _debug y $y | ||||||
|  |      | ||||||
|  |     y64="$(printf $y | tr -d : | _h2b | _base64 | _urlencode)" | ||||||
|  |     _debug y64 $y64 | ||||||
|  |     | ||||||
|  |     jwk='{"kty": "EC", "crv": "'$crv'", "x": "'$x64'", "y": "'$y64'"}' | ||||||
|  |     _debug jwk "$jwk" | ||||||
|  |      | ||||||
|  |     HEADER='{"alg": "ES256", "jwk": '$jwk'}' | ||||||
|  |     HEADERPLACE='{"nonce": "NONCE", "alg": "ES256", "jwk": '$jwk'}' | ||||||
|  | 
 | ||||||
|  |   else | ||||||
|  |     _err "Only RSA or EC key is supported." | ||||||
|  |     return 1 | ||||||
|  |   fi | ||||||
|  | 
 | ||||||
|  |   _debug HEADER "$HEADER" | ||||||
|  | } | ||||||
|  | 
 | ||||||
|  | # url  payload needbase64  keyfile | ||||||
| _send_signed_request() { | _send_signed_request() { | ||||||
|   url=$1 |   url=$1 | ||||||
|   payload=$2 |   payload=$2 | ||||||
|   needbase64=$3 |   needbase64=$3 | ||||||
|    |   keyfile=$4 | ||||||
|  |   if [ -z "$keyfile" ] ; then | ||||||
|  |     keyfile="$ACCOUNT_KEY_PATH" | ||||||
|  |   fi | ||||||
|   _debug url $url |   _debug url $url | ||||||
|   _debug payload "$payload" |   _debug payload "$payload" | ||||||
|    |    | ||||||
|  |   if ! _calcjwk "$keyfile" ; then | ||||||
|  |     return 1 | ||||||
|  |   fi | ||||||
|  |    | ||||||
|   CURL_HEADER="$LE_WORKING_DIR/curl.header" |   CURL_HEADER="$LE_WORKING_DIR/curl.header" | ||||||
|   dp="$LE_WORKING_DIR/curl.dump" |   dp="$LE_WORKING_DIR/curl.dump" | ||||||
|   CURL="curl --silent --dump-header $CURL_HEADER " |   CURL="curl --silent --dump-header $CURL_HEADER " | ||||||
|   if [ "$DEBUG" ] ; then |   if [ "$DEBUG" ] ; then | ||||||
|     CURL="$CURL --trace-ascii $dp " |     CURL="$CURL --trace-ascii $dp " | ||||||
|   fi |   fi | ||||||
|   payload64=$(echo -n $payload | _base64 | _b64) |   payload64=$(echo -n $payload | _base64 | _urlencode) | ||||||
|   _debug payload64 $payload64 |   _debug payload64 $payload64 | ||||||
|    |    | ||||||
|   nonceurl="$API/directory" |   nonceurl="$API/directory" | ||||||
| @ -257,10 +340,10 @@ _send_signed_request() { | |||||||
|   protected="$(printf "$HEADERPLACE" | sed "s/NONCE/$nonce/" )" |   protected="$(printf "$HEADERPLACE" | sed "s/NONCE/$nonce/" )" | ||||||
|   _debug protected "$protected" |   _debug protected "$protected" | ||||||
|    |    | ||||||
|   protected64="$(printf "$protected" | _base64 | _b64)" |   protected64="$(printf "$protected" | _base64 | _urlencode)" | ||||||
|   _debug protected64 "$protected64" |   _debug protected64 "$protected64" | ||||||
|    | 
 | ||||||
|   sig=$(echo -n "$protected64.$payload64" |  openssl   dgst   -sha256  -sign  $ACCOUNT_KEY_PATH | _base64 | _b64) |   sig=$(echo -n "$protected64.$payload64" |  openssl   dgst   -sha256  -sign  "$keyfile" | _base64 | _urlencode) | ||||||
|   _debug sig "$sig" |   _debug sig "$sig" | ||||||
|    |    | ||||||
|   body="{\"header\": $HEADER, \"protected\": \"$protected64\", \"payload\": \"$payload64\", \"signature\": \"$sig\"}" |   body="{\"header\": $HEADER, \"protected\": \"$protected64\", \"payload\": \"$payload64\", \"signature\": \"$sig\"}" | ||||||
| @ -656,7 +739,40 @@ issue() { | |||||||
|   fi |   fi | ||||||
|    |    | ||||||
|   createAccountKey $Le_Domain $Le_Keylength |   createAccountKey $Le_Domain $Le_Keylength | ||||||
|  | 
 | ||||||
|  |   if ! _calcjwk "$ACCOUNT_KEY_PATH" ; then | ||||||
|  |     return 1 | ||||||
|  |   fi | ||||||
|    |    | ||||||
|  |   accountkey_json=$(echo -n "$jwk" |  tr -d ' ' ) | ||||||
|  |   thumbprint=$(echo -n "$accountkey_json" | openssl dgst -sha256 -binary | _base64 | _urlencode) | ||||||
|  |    | ||||||
|  |   accountkeyhash="$(cat "$ACCOUNT_KEY_PATH" | openssl dgst -sha256 -binary | _base64)" | ||||||
|  | 
 | ||||||
|  |   if [ "$accountkeyhash" != "$ACCOUNT_KEY_HASH" ] ; then | ||||||
|  |     _info "Registering account" | ||||||
|  |     regjson='{"resource": "new-reg", "agreement": "'$AGREEMENT'"}' | ||||||
|  |     if [ "$ACCOUNT_EMAIL" ] ; then | ||||||
|  |       regjson='{"resource": "new-reg", "contact": ["mailto: '$ACCOUNT_EMAIL'"], "agreement": "'$AGREEMENT'"}' | ||||||
|  |     fi   | ||||||
|  |     _send_signed_request   "$API/acme/new-reg"  "$regjson" | ||||||
|  |      | ||||||
|  |     if [ "$code" == "" ] || [ "$code" == '201' ] ; then | ||||||
|  |       _info "Registered" | ||||||
|  |       echo $response > $LE_WORKING_DIR/account.json | ||||||
|  |     elif [ "$code" == '409' ] ; then | ||||||
|  |       _info "Already registered" | ||||||
|  |     else | ||||||
|  |       _err "Register account Error: $response" | ||||||
|  |       _clearup | ||||||
|  |       return 1 | ||||||
|  |     fi | ||||||
|  |     ACCOUNT_KEY_HASH="$accountkeyhash" | ||||||
|  |     _saveaccountconf "ACCOUNT_KEY_HASH" "$ACCOUNT_KEY_HASH" | ||||||
|  |   else | ||||||
|  |     _info "Skip register account key" | ||||||
|  |   fi | ||||||
|  | 
 | ||||||
|   if ! createDomainKey $Le_Domain $Le_Keylength ; then  |   if ! createDomainKey $Le_Domain $Le_Keylength ; then  | ||||||
|     _err "Create domain key error." |     _err "Create domain key error." | ||||||
|     return 1 |     return 1 | ||||||
| @ -666,46 +782,6 @@ issue() { | |||||||
|     _err "Create CSR error." |     _err "Create CSR error." | ||||||
|     return 1 |     return 1 | ||||||
|   fi |   fi | ||||||
| 
 |  | ||||||
|   pub_exp=$(openssl rsa -in $ACCOUNT_KEY_PATH  -noout -text | grep "^publicExponent:"| cut -d '(' -f 2 | cut -d 'x' -f 2 | cut -d ')' -f 1) |  | ||||||
|   if [ "${#pub_exp}" == "5" ] ; then |  | ||||||
|     pub_exp=0$pub_exp |  | ||||||
|   fi |  | ||||||
|   _debug pub_exp "$pub_exp" |  | ||||||
|    |  | ||||||
|   e=$(echo $pub_exp | _h2b | _base64) |  | ||||||
|   _debug e "$e" |  | ||||||
|    |  | ||||||
|   modulus=$(openssl rsa -in $ACCOUNT_KEY_PATH -modulus -noout | cut -d '=' -f 2 ) |  | ||||||
|   n=$(echo $modulus| _h2b | _base64 | _b64 ) |  | ||||||
| 
 |  | ||||||
|   jwk='{"e": "'$e'", "kty": "RSA", "n": "'$n'"}' |  | ||||||
|    |  | ||||||
|   HEADER='{"alg": "RS256", "jwk": '$jwk'}' |  | ||||||
|   HEADERPLACE='{"nonce": "NONCE", "alg": "RS256", "jwk": '$jwk'}' |  | ||||||
|   _debug HEADER "$HEADER" |  | ||||||
|    |  | ||||||
|   accountkey_json=$(echo -n "$jwk" |  tr -d ' ' ) |  | ||||||
|   thumbprint=$(echo -n "$accountkey_json" | openssl dgst -sha256 -binary | _base64 | _b64) |  | ||||||
|    |  | ||||||
|    |  | ||||||
|   _info "Registering account" |  | ||||||
|   regjson='{"resource": "new-reg", "agreement": "'$AGREEMENT'"}' |  | ||||||
|   if [ "$ACCOUNT_EMAIL" ] ; then |  | ||||||
|     regjson='{"resource": "new-reg", "contact": ["mailto: '$ACCOUNT_EMAIL'"], "agreement": "'$AGREEMENT'"}' |  | ||||||
|   fi   |  | ||||||
|   _send_signed_request   "$API/acme/new-reg"  "$regjson" |  | ||||||
|    |  | ||||||
|   if [ "$code" == "" ] || [ "$code" == '201' ] ; then |  | ||||||
|     _info "Registered" |  | ||||||
|     echo $response > $LE_WORKING_DIR/account.json |  | ||||||
|   elif [ "$code" == '409' ] ; then |  | ||||||
|     _info "Already registered" |  | ||||||
|   else |  | ||||||
|     _err "Register account Error: $response" |  | ||||||
|     _clearup |  | ||||||
|     return 1 |  | ||||||
|   fi |  | ||||||
|    |    | ||||||
|   vtype="$VTYPE_HTTP" |   vtype="$VTYPE_HTTP" | ||||||
|   if [[ "$Le_Webroot" == "dns"* ]] ; then |   if [[ "$Le_Webroot" == "dns"* ]] ; then | ||||||
| @ -759,7 +835,7 @@ issue() { | |||||||
|         dnsadded='0' |         dnsadded='0' | ||||||
|         txtdomain="_acme-challenge.$d" |         txtdomain="_acme-challenge.$d" | ||||||
|         _debug txtdomain "$txtdomain" |         _debug txtdomain "$txtdomain" | ||||||
|         txt="$(echo -e -n $keyauthorization | openssl dgst -sha256 -binary | _base64 | _b64)" |         txt="$(echo -e -n $keyauthorization | openssl dgst -sha256 -binary | _base64 | _urlencode)" | ||||||
|         _debug txt "$txt" |         _debug txt "$txt" | ||||||
|         #dns |         #dns | ||||||
|         #1. check use api |         #1. check use api | ||||||
| @ -923,7 +999,7 @@ issue() { | |||||||
| 
 | 
 | ||||||
|   _clearup |   _clearup | ||||||
|   _info "Verify finished, start to sign." |   _info "Verify finished, start to sign." | ||||||
|   der="$(openssl req  -in $CSR_PATH -outform DER | _base64 | _b64)" |   der="$(openssl req  -in $CSR_PATH -outform DER | _base64 | _urlencode)" | ||||||
|   _send_signed_request "$API/acme/new-cert" "{\"resource\": \"new-cert\", \"csr\": \"$der\"}" "needbase64" |   _send_signed_request "$API/acme/new-cert" "{\"resource\": \"new-cert\", \"csr\": \"$der\"}" "needbase64" | ||||||
|    |    | ||||||
|    |    | ||||||
| @ -1195,6 +1271,8 @@ _initconf() { | |||||||
| #FORCE=1 # Force to issue cert | #FORCE=1 # Force to issue cert | ||||||
| #DEBUG=1 # Debug mode | #DEBUG=1 # Debug mode | ||||||
| 
 | 
 | ||||||
|  | #ACCOUNT_KEY_HASH=account key hash | ||||||
|  | 
 | ||||||
| #dns api | #dns api | ||||||
| ####################### | ####################### | ||||||
| #Cloudflare: | #Cloudflare: | ||||||
|  | |||||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user