-
Notifications
You must be signed in to change notification settings - Fork 897
Description
Contact Details
No response
Version
Jim/ED25519_SHA2_fix
Description
Library creates an invalid certificate signing request on the ESP32s3 when hardware acceleration is enabled. A valid signing request is generated with hardware acceleration disabled, or the code running on a Windows target. Previously I've seen the same problem on the ESP32 and even with hardware acceleration disabled. Have tested on a recent master branch and also ED25519_SHA2_fix. I used @gojimmypi 's branch as he has a lot of fixes for the Espressif implementation of the library.
Output from the signing command when supplied with a good CSR (ESP32s3 without h/w acceleration):
$ openssl.ex
[user_settings.zip](https://github.com/wolfSSL/wolfssl/files/11007185/user_settings.zip)
e x509 -req -in "Input\BLS-001 - ESP32s3 - no HW acceleration - new key - signing request.csr" -days 10 -CA "CertificateAuthority-4096-PublicKey.crt" -CAkey "CertificateAuthority-4096-PrivateKey.pem" -passin pass:secret -CAcreateserial -extfile "CertificateExtensions.txt" -extensions LumosDevice -out Output\BLS-001-Device-Certificate.crt -text
Certificate request self-signature ok
subject=C = NZ, L = Hamilton, O = "Blue Leaf Software, Ltd", CN = Lumos, serialNumber = BLS-001
Output from the signing command when supplied with a bad CSR (ESP32s3 with h/w acceleration):
$ openssl.exe x509 -req -in "Input\BLS-001 - ESP32s3 - HW acceleration - New private key - Jim ED25519_SHA2_fix -signing request.csr" -days 10 -CA "CertificateAuthority-4096-PublicKey.crt" -CAkey "CertificateAuthority-4096-PrivateKey.pem" -passin pass:secret -CAcreateserial -extfile "CertificateExtensions.txt" -extensions LumosDevice -out Output\BLS-001-Device-Certificate.crt -text
Certificate request self-signature did not match the contents
545B0000:error:0200008A:rsa routines:RSA_padding_check_PKCS1_type_1:invalid padding:crypto\rsa\rsa_pk1.c:75:
545B0000:error:02000072:rsa routines:rsa_ossl_public_decrypt:padding check failed:crypto\rsa\rsa_ossl.c:599:
545B0000:error:1C880004:Provider routines:rsa_verify:RSA lib:providers\implementations\signature\rsa_sig.c:774:
545B0000:error:06880006:asn1 encoding routines:ASN1_item_verify_ctx:EVP lib:crypto\asn1\a_verify.c:217:
If I take the private key that's generated on the device I can create a CSR as below (in Windows), but that produces the same error message as above when I try to sign the CSR as above suggesting the problem might be with the private key.
openssl req -new -key "Input\BLS-001 - ESP32s3 - HW acceleration - New private key - Jim ED25519_SHA2_fix.pem" -nodes -out Output\BLS-001-req.csr
Code used to generate a private key and signing request on the device:
bool CCredentialStore::GenerateCertificate(const char* pchSerial, const char* pAddress)
{
// Generate a new private device key. Using a RSA key because the ESP32 has hardware
// acceleration for that.
// https://www.wolfssl.com/documentation/manuals/wolfssl/chapter07.html#rsa-key-generation
// https://www.wolfssl.com/documentation/manuals/wolfssl/group__Random.html#function-wc_initrng
// https://www.wolfssl.com/documentation/manuals/wolfssl/group__RSA.html#function-wc_initrsakey
// https://www.wolfssl.com/documentation/manuals/wolfssl/group__RSA.html#function-wc_makersakey
// todo: check if this is using the Espressif RNG. If it is, make sure the radio
// is on. The radio is used as an entropy source to make sure that true random
// numbers are generated. If it isn't using the Espressif RNG, maybe it should
// be since that should generate True Random Numbers.
WC_RNG RandomNumberGenerator;
int nResult = wc_InitRng(&RandomNumberGenerator);
if (0 != nResult)
{
ReportError("InitRng", nResult);
return false;
}
unique_ptr<RsaKey> pNewKey(new RsaKey());
nResult = wc_InitRsaKey(pNewKey.get(), nullptr);
if (0 != nResult)
{
ReportError("InitRsaKey", nResult);
return false;
}
nResult = wc_MakeRsaKey(pNewKey.get(), PrivateKeySize, 65537, &RandomNumberGenerator);
if (0 != nResult)
{
ReportError("MakeRsaKey", nResult);
return false;
}
const size_t szPrivateKeyBuffer = 2048;
auto puPrivateKeyDer = make_unique<uint8_t[]>(szPrivateKeyBuffer);
nResult = wc_RsaKeyToDer(pNewKey.get(), puPrivateKeyDer.get(), szPrivateKeyBuffer);
if (nResult > 0)
{
WriteCertificate(puPrivateKeyDer.get(), nResult, PRIVATEKEY_TYPE);
}
else
{
cerr << "Error: wc_RsaKeyToDer\n";
}
// Generate a certificate signing request.
// https://www.wolfssl.com/documentation/manuals/wolfssl/chapter07.html#certificate-signing-request-csr-generation
// https://www.wolfssl.com/documentation/manuals/wolfssl/asn__public_8h.html#function-wc_makecertreq
// https://www.wolfssl.com/documentation/manuals/wolfssl/asn__public_8h.html#function-wc_signcert
unique_ptr<Cert> pRequest(new Cert());
wc_InitCert(pRequest.get());
pRequest->daysValid = 30;
#if IS_WINDOWS
strncpy_s(pRequest->subject.country, "NZ", sizeof(pRequest->subject.country));
strncpy_s(pRequest->subject.org, "Blue Leaf Software, Ltd", sizeof(pRequest->subject.org));
strncpy_s(pRequest->subject.locality, "Hamilton", sizeof(pRequest->subject.locality));
strncpy_s(pRequest->subject.commonName, "Lumos", sizeof(pRequest->subject.commonName));
#else
strncpy(pRequest->subject.country, "NZ", sizeof(pRequest->subject.country));
strncpy(pRequest->subject.org, "Blue Leaf Software, Ltd", sizeof(pRequest->subject.org));
strncpy(pRequest->subject.locality, "Hamilton", sizeof(pRequest->subject.locality));
strncpy(pRequest->subject.commonName, "Lumos", sizeof(pRequest->subject.commonName));
#endif
CFixedStringPrint SerialDev(pRequest->subject.serialDev, sizeof(pRequest->subject.serialDev));
SerialDev << pchSerial;
const size_t szCertificateRequestBuffer = 4096;
auto puCertificateRequest = make_unique<uint8_t[]>(szCertificateRequestBuffer);
int nRequestSize = wc_MakeCertReq(pRequest.get(), puCertificateRequest.get(), szCertificateRequestBuffer, pNewKey.get(), nullptr);
if (nRequestSize <= 0)
{
ReportError("MakeCertReq", nRequestSize);
return false;
}
cout << "SignCert\n";
pRequest->sigType = CTC_SHA256wRSA;
int nCertificateSize = wc_SignCert(pRequest->bodySz, pRequest->sigType, puCertificateRequest.get(), szCertificateRequestBuffer, pNewKey.get(), nullptr, &RandomNumberGenerator);
if (nCertificateSize <= 0)
{
ReportError("SignCert", nCertificateSize);
return false;
}
WriteCertificate(puCertificateRequest.get(), nCertificateSize, CERTREQ_TYPE);
cout << "\ndone.\n";
return true;
}
void CCredentialStore::WriteCertificate(const uint8_t *pDERCertificate, size_t szCertificate, int nType)
{
const size_t szTextRequestBuffer = 4096;
auto puTextRequest = make_unique<uint8_t[]>(szTextRequestBuffer);
memset(puTextRequest.get(), 0, szTextRequestBuffer);
int nPemSize = wc_DerToPem(pDERCertificate, szCertificate, puTextRequest.get(), szTextRequestBuffer, nType);
if (nPemSize <= 0 || nPemSize == szTextRequestBuffer)
{
ReportError("DerToPem", nPemSize);
return;
}
// make sure null terminated.
puTextRequest.get()[nPemSize - 1] = 0;
cout << reinterpret_cast<char*>(puTextRequest.get()) << endl << endl;
}
Also attached, WolfSSL user_settings.zip files, Keys and certificate signing requests.zip
Reproduction steps
No response
Relevant log output
No response