Closed boraozgen closed 3 years ago
The code looks fine, did you by any change changed the certificate stored on the chip eDEVICE_PUBKEY_CERT_IFX
this one?
I do not remember exactly, but I tried a new slot that I flashed myself, which normally works for a TLS connection (where the public key is provided by host). That does not work either.
BTW I just tried the same procedure with OPTIGA_CRYPT_HOST_DATA
and that works. Working code coming in a moment for comparison.
This one works. Using the same slot with OPTIGA_CRYPT_OID_DATA
fails.
// Read client certificate
ret = optiga_util_read_data(eDEVICE_PUBKEY_CERT_PRJSPC_1, CERT_OFFSET, (uint8_t *)clientCert, (uint16_t *)&clientCertLen);
if (OPTIGA_LIB_SUCCESS != ret)
{
tr_error("read client certificate failed with %x", (unsigned int)ret);
return ret;
}
static mbedtls_x509_crt xCertCtx;
memset(&xCertCtx, 0, sizeof(mbedtls_x509_crt));
mbedtls_x509_crt_init(&xCertCtx);
ret = mbedtls_x509_crt_parse(&xCertCtx, (const unsigned char *)clientCert, clientCertLen);
if (0 != ret)
{
tr_error("mbedtls_x509_crt_parse failed with %x", (unsigned int)ret);
mbedtls_x509_crt_free(&xCertCtx);
return ret;
}
static uint8_t optigaSignature[72];
uint16_t optigaSignatureLen = sizeof(optigaSignature);
ret = optiga_crypt_ecdsa_sign(digest, sizeof(digest), OPTIGA_KEY_STORE_ID_E0F1, optigaSignature, &optigaSignatureLen);
if (ret != OPTIGA_LIB_SUCCESS)
{
tr_error("optiga_crypt_ecdsa_sign failed with %x", (unsigned int)ret);
return ret;
}
tr_debug("Generated signature length: %u", optigaSignatureLen);
// Add sequence tag since mbed TLS requires it
static uint8_t signatureWithTag[72];
signatureWithTag[0] = 0x30;
signatureWithTag[1] = optigaSignatureLen;
memcpy(signatureWithTag + 2, optigaSignature, optigaSignatureLen);
ret = mbedtls_pk_verify(
&xCertCtx.pk,
MBEDTLS_MD_SHA256,
digest,
sizeof(digest),
signatureWithTag,
optigaSignatureLen + 2);
if (0 != ret)
{
tr_error("mbedtls_pk_verify failed with %x", (unsigned int)ret);
mbedtls_x509_crt_free(&xCertCtx);
return ret;
}
mbedtls_x509_crt_free(&xCertCtx);
for better understanding can you read out completly the certificate from this OID? You can use this example it should be without any offest. If you would like to write something back to the chip, you can use either the personalize-optiga-trust repo 8the one where you raised the PR), or the python library directly. For the latter you can use this function which does take care of a proper formating. The format is required if you instruct your OPTIGA to verify data using an internally stored certificate.
But you shouldn't have this error (the one you showed before), if you use an Infineon provisioned certificate. If you used your certificate, you need to add 9 bytes of tags prior the certificate to let optiga properly read it and understand internally.
I used the script you mentioned to provision the eDEVICE_PUBKEY_CERT_PRJSPC_1
and OPTIGA_KEY_STORE_ID_E0F1
. Therefore it has the said offset. It still gives 0x29 error.
So let me understand, the snippet you showed originally doesn't give the mentioned error, to get this error you used a user defined certificate, the one you wrote to the trust anchor? Could you please provide if not the whole pubic certificate, but at least first 16 bytes?
First snippet does not work with any slot, even with the eDEVICE_PUBKEY_CERT_PRJSPC_1
slot which is provisioned by personalize-optiga-trust repo.
Here is the first 16 bytes of my certificate:
C0:2:6F:0:2:6C:0:2:69:30:82:2:65:30:82
@boraozgen have you tried extracting the public key from the certificate and feeding it directly to the verify function?
@boraozgen have you tried extracting the public key from the certificate and feeding it directly to the verify function?
Yes, that is what the mbedtls_pk_verify
in my latter example does. Mbedtls extracts the public key and the mbedtls port calls the verify function with OPTIGA_CRYPT_HOST_DATA
and by feeding the public key:
This approach works but the issue is that it does not work using OPTIGA_CRYPT_OID_DATA
, i.e. verifying using the stored certificate.
Understood,
what happens if you write a plain x509 certificate to eDEVICE_PUBKEY_CERT_PRJSPC_2
and reference it when calling the verify function? Does it work for you?
What do you mean by "plain"? I use the personalize-optiga-trust scripts to write the certificates. It automatically adds the offset before the certificate. Should try to write without the offset?
Is there a difference between eDEVICE_PUBKEY_CERT_PRJSPC_1
and eDEVICE_PUBKEY_CERT_PRJSPC_2
? As I mentioned before, I tried with the slot 1 and it did not work.
Should try to write without the offset?
Yes
Is there a difference between eDEVICE_PUBKEY_CERT_PRJSPC_1 and eDEVICE_PUBKEY_CERT_PRJSPC_2? As I mentioned before, I tried with the slot 1 and it did not work
No
I will try it out when I have the time.
The updated python scripts (https://github.com/infineon/python-optiga-trust) write the certificate without the offset. I used it to provision the chip, but I still could not get the verification from OID working.
Hello @boraozgen
good to have you back here! In order to use an OID to verify a signature, you need to have there a DER encoded certficate with no tags prepended, the first byte should be 0x30 (Solution Reference Manual page 77). Can you please confirm this?
You're right, this time I am using a PEM encoded certificate due to chaining requirements in the firmware. It would explain why it does not work this time. I currently cannot try it out with a DER certificate, therefore I will assume this issue is closed. Thank you for your support.
I am trying to verify a signature using a certificate stored in the chip. I keep receiving
INVALID_CERTIFICATE_FORMAT
(0x29) device error although I tried both the IFX certificate and another certificate & key pair I wrote using the personalization scripts. In the solution reference manual it is mentioned that this code can also mean signature verification failure, but I use the following code snippet where the chip signs the digest itself, so that scenario is eliminated. Am I doing something wrong?And this is the output: