Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add support for RSA-PSS #127

Merged
merged 3 commits into from
May 1, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions clippy.toml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
allowed-duplicate-crates = ["base64", "syn"]
15 changes: 11 additions & 4 deletions src/subcommands/create_csr.rs
Original file line number Diff line number Diff line change
Expand Up @@ -182,10 +182,17 @@ impl CreateCsr {
error!("Signing key specifies raw signing only, which is not supported for certificate requests.");
Err(ToolErrorKind::NotSupported.into())
}
AsymmetricSignature::RsaPss { .. } => {
error!("Signing key specifies RSA PSS scheme, which is not supported for certificate requests.");
tgonzalezorlandoarm marked this conversation as resolved.
Show resolved Hide resolved
Err(ToolErrorKind::NotSupported.into())
}
AsymmetricSignature::RsaPss { hash_alg } => match hash_alg {
SignHash::Specific(Hash::Sha256) => Ok(&PKCS_RSA_SHA256),
SignHash::Specific(Hash::Sha384) => Ok(&PKCS_RSA_SHA384),
SignHash::Specific(Hash::Sha512) => Ok(&PKCS_RSA_SHA512),
SignHash::Any => Ok(&PKCS_RSA_SHA256), // Default hash algorithm for the tool.
_ => {
// The algorithm is specific, but not one that RCGEN can use, so fail the operation.
error!("Signing key requires use of hashing algorithm ({:?}), which is not supported for certificate requests.", alg);
Err(ToolErrorKind::NotSupported.into())
}
},
AsymmetricSignature::Ecdsa { hash_alg } => {
if !matches!(
attributes.key_type,
Expand Down
25 changes: 24 additions & 1 deletion src/subcommands/create_rsa_key.rs
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,14 @@ pub struct CreateRsaKey {

/// This command creates RSA encryption keys by default. Supply this flag to create a signing key instead.
/// Signing keys, by default, will specify the SHA-256 hash algorithm and use PKCS#1 v1.5.
/// This has priority over ("r", "for-signing-pss") option.
#[structopt(short = 's', long = "for-signing")]
is_for_signing: bool,

/// Supply this flag to create a signing key with PSS scheme and SHA-256 hash algorithm.
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You should probably make clear both in the code documentation and in the CLI documentation what the "priority" between these two flags is (this one and the previous).

Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Have added comments in the code and also in the CLI about this.

#[structopt(short = 'r', long = "for-signing-pss")]
is_for_signing_pss: bool,

/// Specifies the size (strength) of the key in bits. The default size for RSA keys is 2048 bits.
#[structopt(short = 'b', long = "bits")]
bits: Option<usize>,
Expand All @@ -41,7 +46,8 @@ impl CreateRsaKey {
/// Exports a key.
pub fn run(&self, basic_client: BasicClient) -> Result<()> {
let policy = if self.is_for_signing {
info!("Creating RSA signing key...");
// If both "-s" and "-r" flags are set, then "-s" takes precedence
info!("Creating RSA signing key with PKCS1 v1.5 scheme...");
Policy {
usage_flags: {
let mut usage_flags = UsageFlags::default();
Expand All @@ -57,6 +63,23 @@ impl CreateRsaKey {
}
.into(),
}
} else if self.is_for_signing_pss {
info!("Creating RSA signing key with PSS scheme...");
Policy {
usage_flags: {
let mut usage_flags = UsageFlags::default();
let _ = usage_flags
.set_sign_hash()
.set_verify_hash()
.set_sign_message()
.set_verify_message();
usage_flags
},
permitted_algorithms: AsymmetricSignature::RsaPss {
hash_alg: SignHash::Specific(Hash::Sha256),
}
.into(),
}
} else {
info!("Creating RSA encryption key...");
Policy {
Expand Down
27 changes: 20 additions & 7 deletions tests/parsec-cli-tests.sh
Original file line number Diff line number Diff line change
Expand Up @@ -45,11 +45,13 @@ delete_key() {
create_key() {
# $1 - key type ("RSA" or "ECC")
# $2 - key name
# $3 - key usage ("SIGN" or "OAEP"), only consulted if $1 == "RSA"
# $3 - key usage ("SIGN_PKCS1_V15", "SIGN_PSS" or "OAEP"), only consulted if $1 == "RSA"
KEY="$2"

if [ "$3" = "SIGN" -a "$1" = "RSA" ]; then
if [ "$3" = "SIGN_PKCS1_V15" -a "$1" = "RSA" ]; then
EXTRA_CREATE_KEY_ARGS="--for-signing"
elif [ "$3" = "SIGN_PSS" -a "$1" = "RSA" ]; then
EXTRA_CREATE_KEY_ARGS="--for-signing-pss"
elif [ "$3" = "OAEP" -a "$1" = "RSA" ]; then
EXTRA_CREATE_KEY_ARGS="--oaep"
else
Expand Down Expand Up @@ -96,9 +98,10 @@ test_crypto_provider() {
test_encryption "OAEP"
test_decryption "OAEP"
fi
test_signing "RSA"

test_signing "ECC"
test_csr "RSA"
test_csr "RSA" "SIGN_PKCS1_V15"
test_csr "RSA" "SIGN_PSS"
test_csr "ECC"
test_rsa_key_bits
test_rsa_key_bits 1024
Expand Down Expand Up @@ -180,10 +183,16 @@ test_decryption() {

test_signing() {
# $1 - key type ("RSA" or "ECC")
# $2 - RSA scheme ("SIGN_PKCS1_V15" or "SIGN_PSS")
KEY="anta-key-sign"
TEST_STR="$(date) Parsec signature test"

create_key $1 $KEY "SIGN"
create_key $1 $KEY $2

EXTRA_VERIFY_ARGS=
if [ "$2" = "SIGN_PSS" -a "$1" = "RSA" ]; then
EXTRA_VERIFY_ARGS="-sigopt rsa_padding_mode:pss"
fi

# If the key was successfully created and exported
if [ -s ${MY_TMP}/${KEY}.pem ]; then
Expand All @@ -200,7 +209,7 @@ test_signing() {
run_cmd $OPENSSL base64 -d -a -A -in ${MY_TMP}/${KEY}.sign -out ${MY_TMP}/${KEY}.bin

printf "$TEST_STR" >${MY_TMP}/${KEY}.test_str
run_cmd $OPENSSL dgst -sha256 -verify ${MY_TMP}/${KEY}.pem \
run_cmd $OPENSSL dgst -sha256 -verify ${MY_TMP}/${KEY}.pem ${EXTRA_VERIFY_ARGS} \
-signature ${MY_TMP}/${KEY}.bin ${MY_TMP}/${KEY}.test_str
fi

Expand All @@ -209,13 +218,14 @@ test_signing() {

test_csr() {
# $1 - key type ("RSA" or "ECC")
# $2 - RSA scheme ("SIGN_PKCS1_V15" or "SIGN_PSS")
KEY="anta-key-csr"
TEST_CN="parallaxsecond.com"
TEST_SAN="localhost"
TEST_SERIAL="EZ4U2CIXL"

# CSR creation needs a signing key.
create_key $1 $KEY "SIGN"
create_key $1 $KEY $2

# If the key was successfully created and exported
if [ -s ${MY_TMP}/${KEY}.pem ]; then
Expand Down Expand Up @@ -287,6 +297,9 @@ while [ "$#" -gt 0 ]; do
--no-v1.5 )
NO_PKCS1_V15="true"
;;
--no-pss )
NO_PSS="true"
;;
--rsa-key-size )
shift; RSA_KEY_SIZE=$1
;;
Expand Down
Loading