Skip to content

ZTP downloaded file is not decrypted #65

@quanchuen-cf

Description

@quanchuen-cf

Hello,

There's a Encryption section for ZTP in the main repo:

https://github.com/sonic-net/SONiC/blob/master/doc/ztp/ztp.md#511-encryption-and-authentication

I'm trying to use this in SONiC ZTP, but facing some confusions and discrepancies with system behavior:

  1. it's not decrypting file despite of saying Processed Configuration section 00-download with result SUCCESS, exit code (0). The content of destination file is still encrypted.
  2. I can't match the term fingerprint into this context, is it the digest or hash of the digest of the fingerprint of the rsa pubkey? From the description it sounds like a hash of the digest.
  3. I checked on my /usr/lib/{python,ztp} my SONiC and this colo as well, I can't find any reference to the fingerprint, no does the download plugin looks like it taking care of decryption.

Steps to reproduce:

  1. generate keypairs and decryption key
    openssl genrsa -out ztp_rsa_priv.pem 3072
    openssl rsa -in ./ztp_rsa_priv.pem -pubout -out ./ztp_rsa_pub.pem
    openssl rand 32 > ./decryption_key
  2. Generete some content and encrypt it
    echo world > hello
    openssl aes-256-cbc -e -kfile ./decryption_key -pbkdf2 -in ./hello -out hello.enc
  3. Genereate a ztp.json file, see below for a script I'm using to generate this
  4. copy the ztp_rsa_pub.pem, decryption_key, hello.enc, ztp.json to the admin@sonic:~/
  5. install the files, see below for a script
  6. sudo config ztp enable
  7. sudo ztp run

Expected Result

  1. ztp succeeds
  2. sudo file /home/admin/hello.txt returns text file
  3. sudo cat /home/admin/hello.txt returns world

Observed Result

  1. ztp succeeds
  2. sudo file /home/admin/hello.txt returns hello.txt: openssl enc'd data with salted password
  3. sudo cat /home/admin/hello.txt returns garbage, its content is the same as hello.enc

Logs

sudo ztp run

admin@sonic:~$ sudo ztp run
ZTP will be restarted. You may lose switch data and connectivity, continue?[yes/NO] y
May 22 04:31:12.258433 sonic WARNING sonic-ztp[85904]: Received terminate signal. Shutting down.
admin@sonic:~$ May 22 04:31:13.574672 sonic INFO sonic-ztp[92133]: ZTP service started.
May 22 04:31:13.577935 sonic INFO sonic-ztp[92133]: Starting ZTP using JSON file /host/ztp/ztp_data_local.json at 2025-05-22 04:31:13 UTC.
May 22 04:31:13.578029 sonic INFO sonic-ztp[92133]: Checking running configuration to load ZTP configuration profile.
May 22 04:31:14.115764 sonic INFO sonic-ztp[92144]: Waiting for system online status before continuing ZTP. (This may take 30--120 seconds).
May 22 04:31:14.126955 sonic INFO sonic-ztp[92144]: System is ready to respond.
May 22 04:31:14.427274 sonic INFO sonic-ztp[92144]: Restarting network configuration.
May 22 04:31:20.884064 sonic INFO sonic-ztp[92144]: Restarted network configuration.
May 22 04:31:20.886073 sonic INFO sonic-ztp[92133]: Processing configuration section 00-test-decryption at 2025-05-22 04:31:20 UTC.
May 22 04:31:22.383716 sonic INFO sonic-ztp[92435]: download: Start downloading file 'file:///home/admin/hello.enc'.
May 22 04:31:22.394968 sonic INFO sonic-ztp[92435]: download: Completed downloading the file 'file:///home/admin/hello.enc' to '/home/admin/hello.txt'.
May 22 04:31:22.403812 sonic INFO sonic-ztp[92133]: Processed Configuration section 00-test-decryption with result SUCCESS, exit code (0) at 2025-05-22 04:31:20 UTC.
May 22 04:31:22.404768 sonic INFO sonic-ztp[92133]: Checking configuration section 00-test-decryption result: SUCCESS, ignore-result: False.
May 22 04:31:22.405846 sonic INFO sonic-ztp[92133]: ZTP successfully completed at 2025-05-22 04:31:22 UTC.
May 22 04:31:22.408443 sonic WARNING sonic-ztp[92133]: ZTP completed but startup configuration '/etc/sonic/config_db.json' not found. Waiting for 300 seconds before restarting ZTP.

show version

admin@sonic:~$ show version

SONiC Software Version: SONiC.202305.0-dirty-20240806.215620
SONiC OS Version: 11
Distribution: Debian 11.10
Kernel: 5.10.0-23-2-amd64
Build commit: d449a0640
Build date: Wed Aug  7 03:01:10 UTC 2024
Built by: micasrd@micasrd-PowerEdge-R730

Platform: x86_64-****
HwSKU: -
ASIC: broadcom
ASIC Count: 1
Serial Number: -
Model Number: -
Hardware Revision: 100
Uptime: 04:36:19 up  2:48,  2 users,  load average: 1.00, 1.21, 1.14
Date: Thu 22 May 2025 04:36:19

Docker images:
REPOSITORY                    TAG                              IMAGE ID       SIZE
docker-orchagent              202305.0-dirty-20240806.215620   346a76c37ab4   329MB
docker-orchagent              latest                           346a76c37ab4   329MB
docker-fpm-frr                202305.0-dirty-20240806.215620   766835574e19   348MB
docker-fpm-frr                latest                           766835574e19   348MB
docker-teamd                  202305.0-dirty-20240806.215620   321ac34c796d   317MB
docker-teamd                  latest                           321ac34c796d   317MB
docker-nat                    202305.0-dirty-20240806.215620   590fbfa2078a   320MB
docker-nat                    latest                           590fbfa2078a   320MB
docker-sflow                  202305.0-dirty-20240806.215620   def8ce2c92f7   318MB
docker-sflow                  latest                           def8ce2c92f7   318MB
docker-macsec                 latest                           dbb6d0939807   319MB
docker-syncd-brcm             202305.0-dirty-20240806.215620   6a4bacbf5881   673MB
docker-syncd-brcm             latest                           6a4bacbf5881   673MB
docker-gbsyncd-broncos        202305.0-dirty-20240806.215620   04df004adbf1   349MB
docker-gbsyncd-broncos        latest                           04df004adbf1   349MB
docker-gbsyncd-credo          202305.0-dirty-20240806.215620   51ed0de7d163   322MB
docker-gbsyncd-credo          latest                           51ed0de7d163   322MB
docker-dhcp-relay             latest                           fbf1eb19d60f   307MB
docker-eventd                 202305.0-dirty-20240806.215620   bfa96b5091fa   299MB
docker-eventd                 latest                           bfa96b5091fa   299MB
docker-platform-monitor       202305.0-dirty-20240806.215620   2c4bea79167f   420MB
docker-platform-monitor       latest                           2c4bea79167f   420MB
docker-snmp                   202305.0-dirty-20240806.215620   90824dd5f093   338MB
docker-snmp                   latest                           90824dd5f093   338MB
docker-lldp                   202305.0-dirty-20240806.215620   0634a5b3b6cb   341MB
docker-lldp                   latest                           0634a5b3b6cb   341MB
docker-sonic-telemetry        202305.0-dirty-20240806.215620   2e3384bff44d   386MB
docker-sonic-telemetry        latest                           2e3384bff44d   386MB
docker-mux                    202305.0-dirty-20240806.215620   70ef799cfae3   348MB
docker-mux                    latest                           70ef799cfae3   348MB
docker-database               202305.0-dirty-20240806.215620   66c25723771a   299MB
docker-database               latest                           66c25723771a   299MB
docker-router-advertiser      202305.0-dirty-20240806.215620   25c890914cad   299MB
docker-router-advertiser      latest                           25c890914cad   299MB
docker-sonic-mgmt-framework   202305.0-dirty-20240806.215620   c5d6965b9d03   430MB
docker-sonic-mgmt-framework   latest                           c5d6965b9d03   430MB

The Helper Script For Repro

-> % cat setup_env.sh

#!/bin/bash

set -euo pipefail

generate_keypair() {
	openssl genrsa -out ztp_rsa_priv.pem 3072
	openssl rsa -in ./ztp_rsa_priv.pem -pubout -out ./ztp_rsa_pub.pem
}

generate_decryption_key() {
	openssl rand 32 > ./decryption_key
}

encrypt_payload(){
	openssl aes-256-cbc -e -kfile ./decryption_key -pbkdf2 -in ./hello -out hello.enc
}

decrypt_payload(){
	openssl aes-256-cbc -d -kfile ./decryption_key -pbkdf2 -in ./hello.enc -out hello_decrypted.txt
}

sign(){
	openssl sha256 -sign ./ztp_rsa_priv.pem -out hello.sig ./hello
	CHECKSUM=$(openssl sha256 -r ./hello.sig | cut -d' ' -f1)
	echo '{"ztp":{"00-test-decryption":{"plugin":"download","files":[{"url":{"source":"file:///home/admin/hello.enc","destination":"/home/admin/hello.txt","encrypted":{"fingerprint":"'$CHECKSUM'","fingerprint-hash-algorithm":"SHA-256"}}}],"halt-on-failure":true}}}' > ztp.json
	>&2 echo "generated ztp.json, here's an preview of it:"
	jq . ztp.json
}

verify_sig(){
	openssl sha256 -verify ./ztp_rsa_pub.pem -signature ./hello.sig hello
}

check_euid(){
	if [ "$EUID" -ne 0 ]; then
		echo "This script must be run as root"
		exit 1
	fi
}

check_sonic(){
	if [ "$(hostname)" != "sonic" ]; then
		echo "This script must be run on SONiC"
		exit 2
	fi
}

install(){
	install -D -g root -o root -m 644 ./ztp_rsa_pub.pem /usr/lib/ztp/keys/fingerprint_key.pub
	install -D -g root -o root -m 600 ./decryption_key /usr/lib/ztp/keys/decryption_key
	install -D -g root -o root -m 644 ./ztp.json /host/ztp/ztp_data_local.json
}

show_usage(){
	echo "Simple Field Test Script for SONiC ZTP Encryption Feature"
	echo -e "-----\n"
	echo -e "Usage:"
	echo -e "generate\t-\tgenerates rsa keypair and aes encryption key"
	echo -e "encrypt\t-\tencrypt payload file \"hello\""
	echo -e "decrypt\t-\tverify sig and decrypt payload"
	echo -e "sign\t-\tsign payload, generates json objects to insert into ztp.json"
	echo -e "verify\t-\tverifies signature with openssl, sanity check locally"
	echo -e "install\t-\trun this on SONiC to install the RSA cert and decryption key"
	echo -e "\n\n"
	echo "Instructions"
	echo -e "-----\n"
	echo "Run in this order"
	echo -e "\t0 echo world > hello"
	echo -e "\t1. ./setup_env generate"
	echo -e "\t2. ./setup_env encrypt"
	echo -e "\t3. ./setup_env sign"
	echo -e "\t4. update the url object in ztp.json by inserting the encryption object"
	echo -e "\t4. scp ztp.json setup_env.sh ztp_rsa_pub decryption_key hello.enc admin@sonic:~/"
	echo -e "\t5. admin@sonic:~$ ./setup_env install"
}


if [ "$#" -eq 0 ]; then show_usage; exit 0; fi

ACTION=$1

case $ACTION in
	generate)
		generate_keypair
		generate_decryption_key
		;;
	encrypt)
		encrypt_payload
		;;
	decrypt)
		verify_sig
		decrypt_payload
		;;
	sign)
		sign
		;;
	verify)
		verify_sig
		;;
	install)
		check_euid
		check_sonic
		;;
	*)
		show_usage
esac

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions