Arm Mbed and Pelion Device Management support forum

Need a little help, need to sign a message, don't know how

Hi,
I’m at a loss in the mbedtls API.
I’m writing a small ACME protocol client for embedded systems, in C / C++ and I can’t seem to figure out how to “sign” the message I’m supposed to send.

A linux script based application (certbot) does the same, and produced the valid test JSON message below.
I should “sign” a concatenation of the protected and payload fields, evidently the result is a signature of some 340 bytes (after base64).

The mbedtls calls that I’ve looked into don’t seem fit for that. Also examples such as programs/pkey/rsa_encrypt are limited to 100 characters of input, I have >700 characters of input.

Can you point me to an example that shows what to do, or which calls I should be using ? Stuff like mbedtls_rsa_pkcs1_sign() doesn’t look like the right answer.

Thanks,

Danny
Notes : ACME v2 = RFC8555
The signing I need is JWS, see RFC 7515 (https://tools.ietf.org/html/rfc7515#section-5.1).

Working sample JSON (tell me how to build the contents of the signature field from the two others, plus my RSA key of course) :
{
“protected”: “eyJhbGciOiAiUlMyNTYiLCAiandrIjogeyJuIjogInRjcUR6cU82TnI5QTF4Q05rR01lZnVzZDB5VUQwb0dITDRTV0hXMHR6M1FvWnJzeHNQSXd0cWVCVmZXUkJEYmp2VTY5ZUtldElXSEMwNk1zV19lT1pESElKNjR1ZU13ZHpwR2dodkFlWk5lRkNTY0JsbFhpUEcyTTJnLXZzelFUYlpMRzJLVUhwa1BPaGhHT3g0NzBRYmUxdi1yT1NGSkhkZS1iRmRCcFBPUWZwNHFSbzJHTGs3VGpCRWNTRDh4bjNOMXpoTHhnYmI3RHM1eXhETmNfaUpEZVpvT2ZWajAxN0ZTY2tTaUdPUGt6RktOTFgzbXBnbU5NcEJJbzRVSE5lMkY1STF2N3RhZUg0TDdtVGVacUZ1aUVwUkdGTzdweTh5MzJjOC16alFaNC1UZmd1MkdyVWQzV2lSNzZ5V1ZLSVpVTkRWYlFUY25rUFA2VTFjNFNwdyIsICJlIjogIkFRQUIiLCAia3R5IjogIlJTQSJ9LCAibm9uY2UiOiAiQ2VCVGFuRUpJZ1l6MVUtcl9lU3hVUSIsICJ1cmwiOiAiaHR0cHM6Ly9sb2NhbGhvc3Q6MTQwMDAvc2lnbi1tZS11cCJ9”,
“signature”: “bK93X6ER88u-tUrEo7ycf-Ncm2Ex3RhIg3ZFzNJeAARenE2_KXtnqj2-HNOAGH7ESrrClX-zgRHd4JJ0856lQsbbS1QoGS-cLGzAyx4uA5cIdzddc1zHmKf_v_ScN1XBJLhkid_xy0coSSYSSGIwHV6TVkidhnq1nPVBIDhcmQD02UFkjIvKRp7uNqym7kNSAim7ruuxpE6NY3XxCep1-GPCojykEovz82kld_VG8M9f15vP40mdubCIaijpIhRT0h8i0rScghwfesfDVRab2yy9lLnVeQHy4Fvso569CDrqeb5nTL_vthcYcU-QhbIN7XBH-P_vQ7uCf-wE67Wujw”,
“payload”: “ewogICJ0ZXJtc09mU2VydmljZUFncmVlZCI6IHRydWUsCiAgInJlc291cmNlIjogIm5ldy1yZWciCn0”
}

Hi @DannyBackx
Decoding the protected field, you will see:

{"alg": "RS256", "jwk": {"n": "tcqDzqO6Nr9A1xCNkGMefusd0yUD0oGHL4SWHW0tz3QoZrsxsPIwtqeBVfWRBDbjvU69eKetIWHC06MsW_eOZDHIJ64ueMwdzpGghvAeZNeFCScBllXiPG2M2g-vszQTbZLG2KUHpkPOhhGOx470Qbe1v-rOSFJHde-bFdBpPOQfp4qRo2GLk7TjBEcSD8xn3N1zhLxgbb7Ds5yxDNc_iJDeZoOfVj017FSckSiGOPkzFKNLX3mpgmNMpBIo4UHNe2F5I1v7taeH4L7mTeZqFuiEpRGFO7py8y32c8-zjQZ4-Tfgu2GrUd3WiR76yWVKIZUNDVbQTcnkPP6U1c4Spw", "e": "AQAB", "kty": "RSA"}, "nonce": "CeBTanEJIgYz1U-r_eSxUQ", "url": "https://localhost:14000/sign-me-up"}

This includes the public key (modulus n and exponent e, probably in Base64 format), and the algorithm used.
According to this page, RS256 algorithm is RSA asymmetric encryption and private key signature and HS256 . (HMAC SHA256 symmetric encryption)
The Mbed TLS RSA API expects the payload to sign to be the hash of the payload. This means you will need to first do Hmac256 on the payload, and the RSA verify.
As mentioned in the RFC you referenced, section 5.2:

Validate the JWS Signature against the JWS Signing Input
ASCII(BASE64URL(UTF8(JWS Protected Header)) || ‘.’ ||
BASE64URL(JWS Payload)) in the manner defined for the algorithm
being used, which MUST be accurately represented by the value of
the “alg” (algorithm) Header Parameter, which MUST be present.

So, you should probably do the following, in your case:

rsa_verify( HMAC256("eyJhbGciOiAiUlMyNTYiLCAiandrIjogeyJuIjogInRjcUR6cU82TnI5QTF4Q05rR01lZnVzZDB5VUQwb0dITDRTV0hXMHR6M1FvWnJzeHNQSXd0cWVCVmZXUkJEYmp2VTY5ZUtldElXSEMwNk1zV19lT1pESElKNjR1ZU13ZHpwR2dodkFlWk5lRkNTY0JsbFhpUEcyTTJnLXZzelFUYlpMRzJLVUhwa1BPaGhHT3g0NzBRYmUxdi1yT1NGSkhkZS1iRmRCcFBPUWZwNHFSbzJHTGs3VGpCRWNTRDh4bjNOMXpoTHhnYmI3RHM1eXhETmNfaUpEZVpvT2ZWajAxN0ZTY2tTaUdPUGt6RktOTFgzbXBnbU5NcEJJbzRVSE5lMkY1STF2N3RhZUg0TDdtVGVacUZ1aUVwUkdGTzdweTh5MzJjOC16alFaNC1UZmd1MkdyVWQzV2lSNzZ5V1ZLSVpVTkRWYlFUY25rUFA2VTFjNFNwdyIsICJlIjogIkFRQUIiLCAia3R5IjogIlJTQSJ9LCAibm9uY2UiOiAiQ2VCVGFuRUpJZ1l6MVUtcl9lU3hVUSIsICJ1cmwiOiAiaHR0cHM6Ly9sb2NhbGhvc3Q6MTQwMDAvc2lnbi1tZS11cCJ9.ewogICJ0ZXJtc09mU2VydmljZUFncmVlZCI6IHRydWUsCiAgInJlc291cmNlIjogIm5ldy1yZWciCn0"))

and extract the public key from the protected field, as mentioned.
Please try the former and update on results
Regards,
Mbed TLS Support
Ron