SonarLint complaining about "Use a stronger padding scheme"

96 views
Skip to first unread message

Frank Sapone

unread,
Apr 12, 2024, 12:19:32 PMApr 12
to Crypto++ Users
Hello, I am using Windows 10 Professional x64 with CryptoPP 8.9.0.  It is built with Visual Studio.  We started using SonarQube/SonarLint for SCA during compile and it's been complaining "Use a stronger padding scheme".  Specifically it sees this line:

RSASS<PKCS1v15, SHA256>::Verifier verifier(publicKey);

and complains about the PCKS1v15.  I don't know how to change it to a different type and what other ones are available.  It suggests OAEP for RSA which is what I assume we want.

Thanks,
Frank

Jeffrey Walton

unread,
Apr 12, 2024, 12:20:56 PMApr 12
to Crypto++ Users

Frank Sapone

unread,
Apr 15, 2024, 9:18:44 AMApr 15
to Crypto++ Users
NVM, it appears PSSR is considered more secure and this should work with the verifier.

Thanks,
Frank

Frank Sapone

unread,
Apr 15, 2024, 9:18:49 AMApr 15
to Crypto++ Users
I'm very ignorant to crypto stuff so I was using the following guide:  https://www.cryptopp.com/wiki/X509Certificate

What I am trying to do is use X509Certificates and the certs for the user get generated by the server and is used for validation by checking that the user cert was signed by the server cert.  The RSAES has no "verifier" in the class.  So what do I do here?

Frank

On Friday, April 12, 2024 at 12:20:56 PM UTC-4 Jeffrey Walton wrote:

Frank Sapone

unread,
Apr 15, 2024, 9:58:31 AMApr 15
to Crypto++ Users
I spoke too soon.  So I generated a new cert with openssl with the RSAPSS scheme.  Windows shows the certificate information correctly with subject, not before, not after, etc. correctly.  However, with PEM_Load it fails with BER decode error.  Does PEM_Load not support this or is there additional configuration to do before it can load it in properly?

Thanks,
Frank

Jeffrey Walton

unread,
Apr 15, 2024, 10:00:49 AMApr 15
to cryptop...@googlegroups.com
On Mon, Apr 15, 2024 at 9:18 AM Frank Sapone <franksa...@gmail.com> wrote:
NVM, it appears PSSR is considered more secure and this should work with the verifier

Frank Sapone

unread,
Apr 15, 2024, 10:39:27 AMApr 15
to Crypto++ Users
Hello,

I've tried creating a cert as follows with openssl

openssl genpkey -algorithm rsa-pss -pkeyopt rsa_keygen_bits:2048 -out root.key
openssl req -new -key root.key -out root.csr -config root_req.config
openssl ca -in root.csr -out root.crt -config root.config -selfsign -extfile ca.ext -days 7305
openssl x509 -in root.crt -outform PEM -out root.pem

then in my C++ code:
StringSource ss(certStr, true);

PEM_Load(ss, m_Cert);


It will fail eventually down the path and with some debugging it appears it fails at the         BERDecodeSignatureAlgorithm(tbsCertificate, m_subjectSignatureAlgortihm);. More specifically at       bool parametersPresent = seq.EndReached() ? false : BERDecodeAlgorithmParameters(seq);
 where it reaches BERDecodeAlgorithmParameters.

I have not tried dumpasn as I do not have it installed, but I assume sequence is different and is causing problems.

Basically, I am trying to generate certificate that uses PSS with SHA256 in order to avoid SonarLint complaining about PCKS1v15 being not secure enough.  I am trying to make my web server generate a certificate for the user and the user inputs the cert to an app for verification that it was signed by the server CA.  I am new to crypto and certs so I may be doing some things wrong.  It seems OAEP is the right thing to use but I have no idea how to generate this or use it with cryptopp and x509certificate libs?

Thanks,
Frank
Message has been deleted

Jeffrey Walton

unread,
Apr 16, 2024, 2:07:08 PMApr 16
to cryptop...@googlegroups.com


On Tue, Apr 16, 2024 at 1:44 PM One Sini <one...@gmail.com> wrote:
I wasn't entirely satisfied with the security, so I've adjusted the code. I'm not sure if that helps you, depending on what you're doing with it.

This code uses RSA with OAEP (Optimal Asymmetric Encryption Padding) to avoid security issues like padding oracle attacks. It generates RSA keys with a length of 2048 bits, encrypts the message with OAEP padding, and then decrypts it.

OAEP was a red herring. OP wants to use a RSA signature scheme, not an encryption scheme. (His mention of OAEP was the reason I originally posted a link to RSA Encryption Schemes).

Jeff 

Jeffrey Walton

unread,
Apr 16, 2024, 3:19:47 PMApr 16
to cryptop...@googlegroups.com
On Tue, Apr 16, 2024 at 1:44 PM One Sini <one...@gmail.com> wrote:
I wasn't entirely satisfied with the security, so I've adjusted the code. I'm not sure if that helps you, depending on what you're doing with it.

This code uses RSA with OAEP (Optimal Asymmetric Encryption Padding) to avoid security issues like padding oracle attacks. It generates RSA keys with a length of 2048 bits, encrypts the message with OAEP padding, and then decrypts it.

Best Regards Satoshi

I deleted the message from the group. The *.pdf and *.pages smells of malware.

If you want to provide code, please inline it or provide it as a text attachment.

Jeff

One Sini

unread,
Apr 16, 2024, 7:48:45 PMApr 16
to cryptop...@googlegroups.com
the code 

#include <iostream> 
#include <cryptopp/rsa.h> 
#include <cryptopp/filters.h> 
#include <cryptopp/osrng.h> 
#include <cryptopp/sha.h> 
#include <cryptopp/hex.h> 

int main() {
    // Generate RSA keys with 2048 bits 
    CryptoPP::AutoSeededRandomPool rng; 
    CryptoPP::RSA::PrivateKey  
    privateKey; privateKey.GenerateRandomWithKeySize(rng, 2048); 

    CryptoPP::RSA::PublicKey publicKey; 
    publicKey.AssignFrom(privateKey); 

    // Message 
    std::string message = "secret"; 

   // Encrypt with OAEP padding 
   CryptoPP::RSAES_OAEP_SHA_Encryptor encryptor(publicKey); 
   std::string encrypted; 

   CryptoPP::StringSource(message, true, 
       new CryptoPP::PK_EncryptorFilter(rng, encryptor, 
            new CryptoPP::StringSink(encrypted) 
       )
 ); 

    // Decrypt 
    CryptoPP::RSAES_OAEP_SHA_Decryptor decryptor(privateKey); 
    std::string decrypted; 

    CryptoPP::StringSource(encrypted, true, 
        new CryptoPP::PK_DecryptorFilter(rng, decryptor, 
             new CryptoPP::StringSink(decrypted)
        ) 
 );

    // Print results 
    std::cout << "Original message: " << message << std::endl; 
    std::cout << "Encrypted message (hex): "; 

    CryptoPP::StringSource(encrypted, true, 
        new CryptoPP::HexEncoder( 
            new CryptoPP::FileSink(std::cout)
        ) 
 ); 

    std::cout << std::endl; 
    std::cout << "Decrypted message: " << decrypted << std::endl; 

     return 0;
 }


--
You received this message because you are subscribed to the Google Groups "Crypto++ Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cryptopp-user...@googlegroups.com.
To view this discussion on the web visit https://groups.google.com/d/msgid/cryptopp-users/CAH8yC8%3DwptAsfC1eM0Up37oZt14dok_C3R%3DqLiwSrbUJHiVNSw%40mail.gmail.com.

Frank Sapone

unread,
Apr 16, 2024, 10:53:12 PMApr 16
to Crypto++ Users
This code will be good for encoding a message... but I would like to generate an X509 certificate with RSA PSS with SHA256 and have CryptoPP load, then verify this certificate.  Is this possible to do?

Thanks,
Frank

Frank Sapone

unread,
Apr 16, 2024, 10:53:22 PMApr 16
to Crypto++ Users
I grabbed it but it's not relevant.  I need to have a certificate with RSA PSS that can be read by CryptoPP with the X509Cert lib.  Is it possible to do this?

HELA YAICH

unread,
Apr 17, 2024, 11:43:54 AMApr 17
to Crypto++ Users
Hello, 
(I'm new user of ns3 and crypto) 
I have link errors with Crypto++. These errors indicate that the compiler cannot find certain functions or classes defined in Crypto++. This can happen if Crypto++ is not correctly linked to my project. However, I tried to modify my project's CMakeLists.txt file as follows:
set(target_prefix scratch_)

function(create_scratch source_files)
  # Return early if no sources in the subdirectory
  list(LENGTH source_files number_sources)
  if(number_sources EQUAL 0)
    return()
  endif()

  # If the scratch has more than a source file, we need to find the source with
  # the main function
  set(scratch_src)
  foreach(source_file ${source_files})
    file(READ ${source_file} source_file_contents)
    string(REGEX MATCHALL "main[(| (]" main_position "${source_file_contents}")
    if(CMAKE_MATCH_0)
      set(scratch_src ${source_file})
    endif()
  endforeach()

  if(NOT scratch_src)
    return()
  endif()

  # Get parent directory name
  get_filename_component(scratch_dirname ${scratch_src} DIRECTORY)
  string(REPLACE "${CMAKE_CURRENT_SOURCE_DIR}" "" scratch_dirname
                 "${scratch_dirname}"
  )
  string(REPLACE "/" "_" scratch_dirname "${scratch_dirname}")

  # Get source name
  get_filename_component(scratch_name ${scratch_src} NAME_WE)

  set(target_prefix scratch_)
  if(scratch_dirname)
    # Join the names together if dirname is not the scratch folder
    set(target_prefix scratch${scratch_dirname}_)
  endif()

  # Get source absolute path and transform into relative path
  get_filename_component(scratch_src ${scratch_src} ABSOLUTE)
  get_filename_component(scratch_absolute_directory ${scratch_src} DIRECTORY)
  string(REPLACE "${PROJECT_SOURCE_DIR}" "${CMAKE_OUTPUT_DIRECTORY}"
                 scratch_directory ${scratch_absolute_directory}
  )
  add_executable(${target_prefix}${scratch_name} "${source_files}")
  if(${NS3_STATIC})
    target_link_libraries(
      ${target_prefix}${scratch_name} ${LIB_AS_NEEDED_PRE_STATIC}
      ${lib-ns3-static}
    )
  else()
    target_link_libraries(
      ${target_prefix}${scratch_name} "${ns3-libs}" "${ns3-contrib-libs}"
      "${ns3-external-libs}"
    )
  endif()
  set_runtime_outputdirectory(
    ${scratch_name} ${scratch_directory}/ ${target_prefix}
  )
endfunction()

# Scan *.cc files in ns-3-dev/scratch and build a target for each
file(GLOB single_source_file_scratches CONFIGURE_DEPENDS ${CMAKE_CURRENT_SOURCE_DIR}/*.cc)
foreach(scratch_src ${single_source_file_scratches})
  create_scratch(${scratch_src})
endforeach()

# Scan *.cc files in ns-3-dev/scratch subdirectories and build a target for each
# subdirectory
file(
  GLOB_RECURSE scratch_subdirectories
  CONFIGURE_DEPENDS
  LIST_DIRECTORIES true
  ${CMAKE_CURRENT_SOURCE_DIR}/**
)
# Filter out files
foreach(entry ${scratch_subdirectories})
  if(NOT (IS_DIRECTORY ${entry}))
    list(REMOVE_ITEM scratch_subdirectories ${entry})
  endif()
endforeach()

foreach(subdir ${scratch_subdirectories})
  if(EXISTS ${subdir}/CMakeLists.txt)
    # If the subdirectory contains a CMakeLists.txt file
    # we let the CMake file manage the source files
    #
    # Use this if you want to link to external libraries
    # without creating a module
    add_subdirectory(${subdir})
  else()
    # Otherwise we pick all the files in the subdirectory
    # and create a scratch for them automatically
    file(GLOB scratch_sources CONFIGURE_DEPENDS ${subdir}/*.cc)
    create_scratch("${scratch_sources}")
  endif()
endforeach()
find_external_library(DEPENDENCY_NAME cryptopp
                      HEADER_NAME aes.h
                      LIBRARY_NAME cryptopp
                      SEARCH_PATHS /usr/include/cryptopp)


if(${CRYPTOPP_FOUND}) # Notice that the contents of DEPENDENCY_NAME became a prefix for the _FOUND variable
    find_package(cryptopp REQUIRED)
    include_directories(${CRYPTOPP_INCLUDE_DIRS})
    link_libraries(${CRYPTOPP_LIBRARIES})
endif()
add_executable(${target_prefix}${scratch_name} "fanetex.cc")
target_link_libraries(${target_prefix}${scratch_name} PRIVATE cryptopp)

can you help me to solve this problem ? Thank you Capture d’écran 2024-04-17 114345.png

Frank Sapone

unread,
Apr 24, 2024, 8:38:31 AMApr 24
to Crypto++ Users
Has anyone figured out how to use PSS and SHA256 WITH CryptoPP-PEM?  I also tried reporting this to the issuer tracker at https://github.com/noloader/cryptopp-pem and nobody has replied.  I can't imagine I'm the only person using this library in order to achieve this with X509 Certs.

Thanks,
Frank

Manish sharma

unread,
Apr 24, 2024, 8:42:44 AMApr 24
to cryptop...@googlegroups.com

--
You received this message because you are subscribed to the Google Groups "Crypto++ Users" group.
To unsubscribe from this group and stop receiving emails from it, send an email to cryptopp-user...@googlegroups.com.


--
Kind Regards, 
Manish Kr. Sharma 
Digital Marketing Manager




One Sini

unread,
Apr 24, 2024, 1:52:05 PMApr 24
to cryptop...@googlegroups.com
Test this way

a basic guide on how to generate an RSA key pair with PSS padding, sign an X509 certificate with the private key, and verify the signature with the public key using the Crypto++ library:

  1. Generating an RSA Key Pair with PSS Padding:

cpp

Copy code

#include <cryptopp/rsa.h>

#include <cryptopp/osrng.h>

#include <cryptopp/pssr.h>


using namespace CryptoPP;


void generateRSAKeyPair(RSA::PrivateKey& privateKey, RSA::PublicKey& publicKey) {

    AutoSeededRandomPool rng;


    InvertibleRSAFunction params;

    params.GenerateRandomWithKeySize(rng, 2048);


    privateKey = RSA::PrivateKey(params);

    publicKey = RSA::PublicKey(params);

}


int main() {

    RSA::PrivateKey privateKey;

    RSA::PublicKey publicKey;


    generateRSAKeyPair(privateKey, publicKey);


    // The RSA key pair has been generated and is now available

    return 0;

}

  1. Signing the X509 Certificate with the Private Key:

cpp


Copy code

#include <cryptopp/cryptlib.h>

#include <cryptopp/oids.h>

#include <cryptopp/rsa.h>

#include <cryptopp/sha.h>

#include <cryptopp/filters.h>

#include <cryptopp/base64.h>


using namespace CryptoPP;


void signCertificate(const RSA::PrivateKey& privateKey, const X509& certificate, byte* signature) {

    // Implement the process of signing the certificate here

    // Use privateKey and certificate to sign the certificate

}


int main() {

    // Load or create your X509 certificate

    // Here, we assume you already have an X509 certificate


    RSA::PrivateKey privateKey;

    // Load or generate your private key

    // Here, we assume you already have a private key


    byte signature[256]; // Space for the signature


    signCertificate(privateKey, certificate, signature);


    // The certificate has been signed, and the signature is now available

    return 0;

}

  1. Verifying the Signature with the Public Key:

cpp


Copy code

#include <cryptopp/rsa.h>

#include <cryptopp/sha.h>

#include <cryptopp/filters.h>

#include <cryptopp/base64.h>


using namespace CryptoPP;


bool verifySignature(const RSA::PublicKey& publicKey, const X509& certificate, const byte* signature) {

    // Implement the process of verifying the signature here

    // Use publicKey, certificate, and signature


    // Return true if the signature is valid, otherwise false

    return false;

}


int main() {

    // Load or create your X509 certificate

    // Here, we assume you already have an X509 certificate


    RSA::PublicKey publicKey;

    // Load or generate your public key

    // Here, we assume you already have a public key


    byte signature[256]; // Take the signature from the certificate signature


    bool isValid = verifySignature(publicKey, certificate, signature);


    // Check if the signature is valid

    return 0;

}

These code snippets serve as a foundation. You will need to adapt them according to your specific implementation, including the loading process for the X509 certificate and the private/public keys. Remember to include error handling and handle edge cases in your implementation

I hope this help you
;)

One Sini

unread,
Apr 24, 2024, 1:59:49 PMApr 24
to cryptop...@googlegroups.com

This code demonstrates how to load an X509 certificate and private/public keys from files. 


#include <iostream>

#include <fstream>

#include <string>


#include <cryptopp/rsa.h>

#include <cryptopp/files.h>

#include <cryptopp/base64.h>

#include <cryptopp/osrng.h>

#include <cryptopp/pssr.h>


using namespace CryptoPP;

using namespace std;


void loadX509Certificate(const string& certFile, X509Certificate& certificate) {

    ifstream file(certFile.c_str(), ios::in | ios::binary);

    if (!file) {

        cerr << "Error: Failed to open certificate file." << endl;

        // Handle error appropriately

        return;

    }


    try {

        PEM_Load(file, certificate);

    } catch (const Exception& ex) {

        cerr << "Error: Failed to load X509 certificate - " << ex.what() << endl;

        // Handle error appropriately

        return;

    }

}


void loadPrivateKey(const string& privateKeyFile, RSA::PrivateKey& privateKey) {

    ifstream file(privateKeyFile.c_str());

    if (!file) {

        cerr << "Error: Failed to open private key file." << endl;

        // Handle error appropriately

        return;

    }


    try {

        PEM_Load(file, privateKey);

    } catch (const Exception& ex) {

        cerr << "Error: Failed to load private key - " << ex.what() << endl;

        // Handle error appropriately

        return;

    }

}


void loadPublicKey(const string& publicKeyFile, RSA::PublicKey& publicKey) {

    ifstream file(publicKeyFile.c_str());

    if (!file) {

        cerr << "Error: Failed to open public key file." << endl;

        // Handle error appropriately

        return;

    }


    try {

        PEM_Load(file, publicKey);

    } catch (const Exception& ex) {

        cerr << "Error: Failed to load public key - " << ex.what() << endl;

        // Handle error appropriately

        return;

    }

}


int main() {

    string certFile = "certificate.pem";

    string privateKeyFile = "private.key";

    string publicKeyFile = "public.key";


    X509Certificate certificate;

    RSA::PrivateKey privateKey;

    RSA::PublicKey publicKey;


    loadX509Certificate(certFile, certificate);

    loadPrivateKey(privateKeyFile, privateKey);

    loadPublicKey(publicKeyFile, publicKey);


    // Continue with using the certificate and keys...


    return 0;

}



Frank Sapone

unread,
Apr 25, 2024, 8:59:01 AMApr 25
to Crypto++ Users
I based my code off the stuff in the wiki.  So what am I doing wrong?  I just want the PSS to make the SCA shut up.

bool X509CertMod::CheckCertDate(bool bNotBefore)
{
bool bRetValue;
if (bNotBefore)
{
bRetValue = CertIsCurrentTimeAfter(notBeforeDate);
//printf("Created: %02d %02d, %02d %02d:%02d:%02dZ\n", monthInt, dayInt, yearInt, hoursInt, minutesInt, secondsInt);
if (bRetValue)
{
//printf("* NotBefore in past.  Can use.\n");
return true;
}
else
{
//printf("* NotBefore in future.  Can't use!\n");
return false;
}
}
else
{
bRetValue = CertIsCurrentTimeAfter(notAfterDate);
//printf("Expires: %02d %02d, %02d %02d:%02d:%02dZ\n", monthInt, dayInt, yearInt, hoursInt, minutesInt, secondsInt);
if (bRetValue)
{
//printf("* NotAfter in past.  Can't use!\n");
return false;
}
else
{
//printf("* NotAfter in future.  Can use.\n");
return true;
}
}

return false;
}

bool X509CertMod::LoadX509PEMCertificateFromString(const std::string &certStr)
{
try
{

StringSource ss(certStr, true);

PEM_Load(ss, m_Cert);
m_CertStr = certStr;

notBeforeDate.SetDate(m_Cert.GetNotBefore().EncodeValue().c_str());
notAfterDate.SetDate(m_Cert.GetNotAfter().EncodeValue().c_str());
bLoaded = true;
return true;
}
catch (const std::exception &ex)
{
printf("Failed to load cert string: %s\n", ex.what());
}

return false;
}

bool X509CertMod::VerifyCert(void)
{
const SecByteBlock &signature = m_Cert.GetCertificateSignature();
const SecByteBlock &toBeSigned = m_Cert.GetToBeSigned();
const X509PublicKey &publicKey = m_Cert.GetSubjectPublicKey();

if (CheckCertDate(true))
{
if (CheckCertDate(false))
{

RSASS<PKCS1v15, SHA256>::Verifier verifier(publicKey);
bool result = verifier.VerifyMessage(toBeSigned, toBeSigned.size(), signature, signature.size());
if (result)
{
//std::cout << "Verified root certificate" << std::endl;
return true;
}

//std::cout << "Failed to verify root certificate" << std::endl;
}
}

return false;
}

One Sini

unread,
Apr 25, 2024, 1:47:15 PMApr 25
to cryptop...@googlegroups.com
I hope this can you help 

Missing Definitions: Your code snippet lacks definitions for functions such as CertIsCurrentTimeAfter, PEM_Load, SetDate, and others. Make sure these functions are defined somewhere in the code or declared in the appropriate header files.

Uninitialized Variables: The variables notBeforeDate and notAfterDate are used in the LoadX509PEMCertificateFromString function, but it's not shown how they are initialized. If they don't have valid values, this could lead to unexpected behavior.

Return Values in LoadX509PEMCertificateFromString: If an exception is thrown and the function LoadX509PEMCertificateFromString returns false, the code continues to execute as if the certificate had been loaded. Make sure that in case of an error, the function exits early.

Potential Memory Leaks: There's no indication that the memory allocated for notBeforeDate and notAfterDate in LoadX509PEMCertificateFromString is freed. Ensure that memory is properly managed to avoid memory leaks.

Unnecessary Code: In the CheckCertDate function, there's an unnecessary section at the end that reaches return false. This section is unreachable and can be removed.

Unused Variables: In the VerifyCert function, variables such as signature, toBeSigned, and publicKey are declared but not used. Verify if they are actually needed and remove them if not to simplify the code.


Have nice Day 

Reply all
Reply to author
Forward
Message has been deleted
0 new messages