@@ -15,7 +15,7 @@ LEAF_ALGO="" # Defaults to CA_ALGO if not explicitly set
1515CA_HASH=" sha256" # Hash used for cert signatures throughout the chain
1616
1717# Whitelists
18- SUPPORTED_ALGOS=" ecc256 ecc384 rsa2048 rsa3072 rsa4096"
18+ SUPPORTED_ALGOS=" ecc256 ecc384 rsa2048 rsa3072 rsa4096 rsapss2048 rsapss3072 rsapss4096 "
1919SUPPORTED_HASHES=" sha256 sha384 sha512"
2020
2121is_supported_algo () {
@@ -35,16 +35,18 @@ is_supported_hash() {
3535}
3636
3737# Helper functions for key operations. Each takes the target algo as $1.
38+ # rsapss* tokens carry an RSA key plus a PSS padding intent — the key
39+ # itself is generated/handled identically to plain rsa*.
3840generate_private_key () {
3941 local algo=$1
4042 local output_file=$2
4143
4244 case " $algo " in
43- ecc256) openssl ecparam -genkey -name prime256v1 -noout -out " $output_file " ;;
44- ecc384) openssl ecparam -genkey -name secp384r1 -noout -out " $output_file " ;;
45- rsa2048) openssl genrsa -out " $output_file " 2048 ;;
46- rsa3072) openssl genrsa -out " $output_file " 3072 ;;
47- rsa4096) openssl genrsa -out " $output_file " 4096 ;;
45+ ecc256) openssl ecparam -genkey -name prime256v1 -noout -out " $output_file " ;;
46+ ecc384) openssl ecparam -genkey -name secp384r1 -noout -out " $output_file " ;;
47+ rsa2048|rsapss2048 ) openssl genrsa -out " $output_file " 2048 ;;
48+ rsa3072|rsapss3072 ) openssl genrsa -out " $output_file " 3072 ;;
49+ rsa4096|rsapss4096 ) openssl genrsa -out " $output_file " 4096 ;;
4850 * ) echo " Unsupported algo: $algo " >&2 ; exit 1 ;;
4951 esac
5052}
@@ -58,7 +60,7 @@ convert_key_to_der() {
5860 ecc256|ecc384)
5961 openssl ec -in " $input_file " -outform DER -out " $output_file "
6062 ;;
61- rsa2048|rsa3072|rsa4096)
63+ rsa2048|rsa3072|rsa4096|rsapss2048|rsapss3072|rsapss4096 )
6264 openssl rsa -in " $input_file " -outform DER -out " $output_file "
6365 ;;
6466 * ) echo " Unsupported algo: $algo " >&2 ; exit 1 ;;
@@ -79,7 +81,7 @@ extract_public_key() {
7981 ecc256|ecc384)
8082 openssl ec -pubin -in " $pubkey_pem " -outform DER -out " $pubkey_der "
8183 ;;
82- rsa2048|rsa3072|rsa4096)
84+ rsa2048|rsa3072|rsa4096|rsapss2048|rsapss3072|rsapss4096 )
8385 openssl rsa -pubin -in " $pubkey_pem " -outform DER -out " $pubkey_der "
8486 ;;
8587 * ) echo " Unsupported algo: $algo " >&2 ; exit 1 ;;
@@ -94,13 +96,27 @@ validate_key_format() {
9496 ecc256|ecc384)
9597 openssl ec -in " $key_file " -noout
9698 ;;
97- rsa2048|rsa3072|rsa4096)
99+ rsa2048|rsa3072|rsa4096|rsapss2048|rsapss3072|rsapss4096 )
98100 openssl rsa -in " $key_file " -noout
99101 ;;
100102 * ) echo " Unsupported algo: $algo " >&2 ; exit 1 ;;
101103 esac
102104}
103105
106+ # Build openssl -sigopt args for a given algo + hash. For rsapss* algos
107+ # we ask openssl to use PSS padding with salt length equal to the digest
108+ # length and MGF1 keyed by the same hash (the standard interoperable
109+ # choice that wolfCrypt's PSS verify expects). Empty for non-PSS algos.
110+ sig_opts_for_algo () {
111+ local algo=$1
112+ local hash=$2
113+ case " $algo " in
114+ rsapss* )
115+ echo " -sigopt rsa_padding_mode:pss -sigopt rsa_pss_saltlen:digest -sigopt rsa_mgf1_md:$hash "
116+ ;;
117+ esac
118+ }
119+
104120usage () {
105121 cat << EOT
106122Usage: $0 [options]
@@ -191,6 +207,14 @@ if [[ -z "$LEAF_ALGO" ]]; then
191207 LEAF_ALGO=" $CA_ALGO "
192208fi
193209
210+ # Resolve PSS sigopts once based on the selected algos. CA_SIG_OPTS
211+ # applies to every cert signed by a CA-tier key (root self-sig,
212+ # intermediate CSR self-sig, intermediate cert, leaf cert); LEAF_SIG_OPTS
213+ # applies to the leaf CSR self-sig only (the leaf cert itself is signed
214+ # by the intermediate's CA-tier key). Both are empty for non-PSS algos.
215+ CA_SIG_OPTS=$( sig_opts_for_algo " $CA_ALGO " " $CA_HASH " )
216+ LEAF_SIG_OPTS=$( sig_opts_for_algo " $LEAF_ALGO " " $CA_HASH " )
217+
194218# Configuration
195219ROOT_SUBJECT=" /C=US/ST=California/L=San Francisco/O=MyOrganization/OU=Root CA/CN=My Root CA"
196220INTERMEDIATE_SUBJECT=" /C=US/ST=California/L=San Francisco/O=MyOrganization/OU=Intermediate CA/CN=My Intermediate CA"
@@ -210,7 +234,7 @@ echo "Generating Root CA..."
210234generate_private_key " $CA_ALGO " " ${OUTPUT_DIR} /temp/root.key.pem"
211235
212236# Create PEM format root certificate (temporary)
213- openssl req -new -x509 -days 3650 -$CA_HASH \
237+ openssl req -new -x509 -days 3650 -$CA_HASH $CA_SIG_OPTS \
214238 -key ${OUTPUT_DIR} /temp/root.key.pem \
215239 -out ${OUTPUT_DIR} /temp/root.crt.pem \
216240 -subj " $ROOT_SUBJECT " \
@@ -225,13 +249,13 @@ openssl x509 -in ${OUTPUT_DIR}/temp/root.crt.pem -outform DER -out ${OUTPUT_DIR}
225249echo " Generating Intermediate CA..."
226250generate_private_key " $CA_ALGO " " ${OUTPUT_DIR} /temp/intermediate.key.pem"
227251
228- openssl req -new -$CA_HASH \
252+ openssl req -new -$CA_HASH $CA_SIG_OPTS \
229253 -key ${OUTPUT_DIR} /temp/intermediate.key.pem \
230254 -out ${OUTPUT_DIR} /temp/intermediate.csr \
231255 -subj " $INTERMEDIATE_SUBJECT "
232256
233257# Step 3: Sign Intermediate certificate with Root
234- openssl x509 -req -days 1825 -$CA_HASH \
258+ openssl x509 -req -days 1825 -$CA_HASH $CA_SIG_OPTS \
235259 -in ${OUTPUT_DIR} /temp/intermediate.csr \
236260 -out ${OUTPUT_DIR} /temp/intermediate.crt.pem \
237261 -CA ${OUTPUT_DIR} /temp/root.crt.pem \
258282# Create CSR for leaf certificate (CSR is signed by leaf key, but the
259283# resulting cert signature is set by the CA when signing - so the CSR
260284# self-signature uses CA_HASH for consistency).
261- openssl req -new -$CA_HASH \
285+ openssl req -new -$CA_HASH $LEAF_SIG_OPTS \
262286 -key ${OUTPUT_DIR} /temp/leaf.key.pem \
263287 -out ${OUTPUT_DIR} /temp/leaf.csr \
264288 -subj " $LEAF_SUBJECT "
265289
266290# Step 5: Sign Leaf certificate with Intermediate (uses CA_HASH)
267- openssl x509 -req -days 365 -$CA_HASH \
291+ openssl x509 -req -days 365 -$CA_HASH $CA_SIG_OPTS \
268292 -in ${OUTPUT_DIR} /temp/leaf.csr \
269293 -out ${OUTPUT_DIR} /temp/leaf.crt.pem \
270294 -CA ${OUTPUT_DIR} /temp/intermediate.crt.pem \
0 commit comments