Hi, I recently had to do some PKCS#7 signature validation and was disappointed to find that it didn't just work. After digging through RFCs to figure out the myriad of things I'd done wrong I was also left with a lack of 3 features in mbedtls:
1. The full certificate chain was not being loaded and explicitly not supported. I believe this is in error since the certificate was never actually used anywhere, meaning it basically errored out for no reason. Since this certificate chain also contains the key used to validate the signature in my case that presented a pretty fundamental problem.
2. signedAttributes were not supported at all.
3. All the fields in mbedtls_pkcs7 and its associated structures are marked as MBEDTLS_PRIVATE. I need to inspect both the certificates and the signedAttributes and would rather not have to parse the entire DER myself.
I have attached patches implementing the first two. I believe I've done so without altering the behavior of the calls although I'm a bit unsure as to why mbedtls_x509_crt_verify doesn't take a const mbedtls_x509_crt. The third issue is a matter of policy and I don't know what your opinion on it is. For the moment I can at least get away with poking at the internal fields.
I have tested it on several signatures, one of which I have included here and I apologize in advance for the absolute spew but I thought it better than attaching even more files.
The data: 3059301306072A8648CE3D020106082A8648CE3D030107034200041B58AEE5B7C868AE0EED554133774B7C16802062EC2EB5A1A053318A9ED7DB943CE1F877671DADCFEB4D3171ACC2714ECBC0C0BCADE0569DF7CD0031623AF1BBDE72D8FFF60EC6D04B0D6C93658FC40F4AF2E22E1F68BF1A500FE00A94B804B7CA1DD7AF825C000FCF77A0ABB6918D2DF55C7A3CBC90BE14C59D8EE62A02B988DF7F32117770012AE362C03FB3AA3918AB9D10BE78442EFA7FCBA3CB02D6E196CE4137C6C3F280D963A5CD050EAC8871B3EB2C4500916FB3E39840D8EB198D58F49A434B2736385075BF9397405360B8694D0AD1E5DA8291F9EA47743F803F4A409EA72C2DF94F43DB60A0EAB8A8BD409C4D684200778B23D2A8126827995C3A80CAACA4AB7077266CED79BF91725330C9FCE3B8F1F5316C08C17B9994CF0ECB26D87A5C1F8FEB1FA737F78794895F6C5153B575EF8E95A8D433FD9486AA6C2B46ED6633D2BE0938202B99BEC21895018FB6FC59BAD662815A2C65200B8B1BAA4B69A8C89204B1EA70094026E9F710E599E14941476C8CD2E2879CF58E850DC732A506885F646BB9BE96B7A65355A6A9B907956E6DF65336504300CF062BA9DE50
It's SHA2-256 hash is: C76DE7AF191C16E01405CE8FE89136EB60AC035B3DDE34ACF65220AC7C3CA619
If you decode the signature DER you'll see a matching id-messageDigest in the signedAttributes towards the very bottom.
The signature in DER format: 3082089B06092A864886F70D010702A082088C30820888020101310D300B0609608648016503040201300B06092A864886F70D010701A08206D9308203E330820388A00302010202084C304149519D5436300A06082A8648CE3D040302307A312E302C06035504030C254170706C65204170706C69636174696F6E20496E746567726174696F6E204341202D20473331263024060355040B0C1D4170706C652043657274696669636174696F6E20417574686F7269747931133011060355040A0C0A4170706C6520496E632E310B3009060355040613025553301E170D3139303531383031333235375A170D3234303531363031333235375A305F3125302306035504030C1C6563632D736D702D62726F6B65722D7369676E5F5543342D50524F4431143012060355040B0C0B694F532053797374656D7331133011060355040A0C0A4170706C6520496E632E310B30090603550406130255533059301306072A8648CE3D020106082A8648CE3D03010703420004C21577EDEBD6C7B2218F68DD7090A1218DC7B0BD6F2C283D846095D94AF4A5411B83420ED811F3407E83331F1C54C3F7EB3220D6BAD5D4EFF49289893E7C0F13A38202113082020D300C0603551D130101FF04023000301F0603551D2304183016801423F249C44F93E4EF27E6C4F6286C3FA2BBFD2E4B304506082B0601 050507010104393037303506082B060105050730018629687474703A2F2F6F6373702E6170706C652E636F6D2F6F63737030342D6170706C65616963613330323082011D0603551D2004820114308201103082010C06092A864886F7636405013081FE3081C306082B060105050702023081B60C81B352656C69616E6365206F6E207468697320636572746966696361746520627920616E7920706172747920617373756D657320616363657074616E6365206F6620746865207468656E206170706C696361626C65207374616E64617264207465726D7320616E6420636F6E646974696F6E73206F66207573652C20636572746966696361746520706F6C69637920616E642063657274696669636174696F6E2070726163746963652073746174656D656E74732E303606082B06010505070201162A687474703A2F2F7777772E6170706C652E636F6D2F6365727469666963617465617574686F726974792F30340603551D1F042D302B3029A027A0258623687474703A2F2F63726C2E6170706C652E636F6D2F6170706C6561696361332E63726C301D0603551D0E041604149457DB6FD57481868989762F7E578507E79B5824300E0603551D0F0101FF040403020780300F06092A864886F76364061D04020500300A06082A8648CE3D0403020349003046022100BE09571FE71E1E7 35B55E5AFACB4C72FEB445F30185222C7251002B61EBD6F55022100D18B350A5DD6DD6EB1746035B11EB2CE87CFA3E6AF6CBD8380890DC82CDDAA63308202EE30820275A0030201020208496D2FBF3A98DA97300A06082A8648CE3D0403023067311B301906035504030C124170706C6520526F6F74204341202D20473331263024060355040B0C1D4170706C652043657274696669636174696F6E20417574686F7269747931133011060355040A0C0A4170706C6520496E632E310B3009060355040613025553301E170D3134303530363233343633305A170D3239303530363233343633305A307A312E302C06035504030C254170706C65204170706C69636174696F6E20496E746567726174696F6E204341202D20473331263024060355040B0C1D4170706C652043657274696669636174696F6E20417574686F7269747931133011060355040A0C0A4170706C6520496E632E310B30090603550406130255533059301306072A8648CE3D020106082A8648CE3D03010703420004F017118419D76485D51A5E25810776E880A2EFDE7BAE4DE08DFC4B93E13356D5665B35AE22D097760D224E7BBA08FD7617CE88CB76BB6670BEC8E82984FF5445A381F73081F4304606082B06010505070101043A3038303606082B06010505073001862A687474703A2F2F6F6373702E6170706C 652E636F6D2F6F63737030342D6170706C65726F6F7463616733301D0603551D0E0416041423F249C44F93E4EF27E6C4F6286C3FA2BBFD2E4B300F0603551D130101FF040530030101FF301F0603551D23041830168014BBB0DEA15833889AA48A99DEBEBDEBAFDACB24AB30370603551D1F0430302E302CA02AA0288626687474703A2F2F63726C2E6170706C652E636F6D2F6170706C65726F6F74636167332E63726C300E0603551D0F0101FF0404030201063010060A2A864886F7636406020E04020500300A06082A8648CE3D040302036700306402303ACF7283511699B186FB35C356CA62BFF417EDD90F754DA28EBEF19C815E42B789F898F79B599F98D5410D8F9DE9C2FE0230322DD54421B0A305776C5DF3383B9067FD177C2C216D964FC6726982126F54F87A7D1B99CB9B0989216106990F09921D3182018830820184020101308186307A312E302C06035504030C254170706C65204170706C69636174696F6E20496E746567726174696F6E204341202D20473331263024060355040B0C1D4170706C652043657274696669636174696F6E20417574686F7269747931133011060355040A0C0A4170706C6520496E632E310B300906035504061302555302084C304149519D5436300B0609608648016503040201A08193301806092A864886F70D010903310B06092A864 886F70D010701301C06092A864886F70D010905310F170D3233303230393231333032345A302806092A864886F70D010934311B3019300B0609608648016503040201A10A06082A8648CE3D040302302F06092A864886F70D01090431220420C76DE7AF191C16E01405CE8FE89136EB60AC035B3DDE34ACF65220AC7C3CA619300A06082A8648CE3D04030204473045022100EE9B221CD9B5EEB1C6AF4160128D099C9414440A96C855A789846599E3BDE442022005AE51DC947E0B2AA6593E8FDB9F888782C71E5BB1CB6BF3C32B79C448C6A75D
Joakim
Hi, I recently had to do some PKCS#7 signature validation and was disappointed to find that it didn't just work. After digging through RFCs to figure out the myriad of things I'd done wrong I was also left with a lack of 3 features in mbedtls:
- The full certificate chain was not being loaded and explicitly not
supported.
I am not sure if this is relevant but there is a patch for mbedtls which can read the root cert list from a file
https://github.com/mongoose-os/mbedtls
It takes a few days to implement and debug, but it works and gets around the need for ~200k of free RAM for loading the whole root cert chain which is currently ~200k (cacert.pem, 218k).
You need to re-do this each time you upgrade mbedtls, obviously...
It's a pretty important patch which should be in there as standard. Otherwise, mbedtls is usable mainly for single private server hosts.
On Tue, 21 Feb 2023 18:11:54 +0000, Peter via mbed-tls mbed-tls@lists.trustedfirmware.org wrote:
Hi, I recently had to do some PKCS#7 signature validation and was disappointed to find that it didn't just work. After digging through RFCs to figure out the myriad of things I'd done wrong I was also left with a lack of 3 features in mbedtls:
- The full certificate chain was not being loaded and explicitly not
supported.
I am not sure if this is relevant but there is a patch for mbedtls which can read the root cert list from a file
https://github.com/mongoose-os/mbedtls
It takes a few days to implement and debug, but it works and gets around the need for ~200k of free RAM for loading the whole root cert chain which is currently ~200k (cacert.pem, 218k).
You need to re-do this each time you upgrade mbedtls, obviously...
It's a pretty important patch which should be in there as standard. Otherwise, mbedtls is usable mainly for single private server hosts.
I don't think it's relevant. The full certificate chain I'm referring to is not the list of CA certs but the certs embedded in the PKCS#7 signature. In this case it's 2 certs and I need to verify validity back to a single known root.
Hi Joakim,
The current PKCS #7 implementation indeed does not currently support certificate chains, and does not use a certificate from the PKCS #7 file to validate the signature, and does not support authenticatedAttributes.
We’ve tried to document these limitations clearly in include/mbedtls/pkcs7.h – if you think it’s not sufficiently clear, please raise an issue or PR with points for further improvement. We are currently tidying up the existing PKCS #7 functionality so want to get this right before the next release.
Regarding use of MBEDTLS_PRIVATE – if there are particular fields that it’s useful to access, the preferred approach would probably be to add functions to the PKCS #7 API to access the fields in question, rather than remove MBEDTLS_PRIVATE.
Thank you for providing these patches. Would you be able to submit them as a PR for review in the normal way via GitHub (see https://github.com/Mbed-TLS/mbedtls/blob/development/CONTRIBUTING.md for details)? They would also need some tests adding. If you don’t have time to work on these, I can create a PR but would need you to confirm that these submissions are made under the terms of our DCO.
Thanks
Dave Rodgman
From: Joakim Sindholt via mbed-tls mbed-tls@lists.trustedfirmware.org Date: Tuesday, 21 February 2023 at 11:30 To: mbed-tls@lists.trustedfirmware.org mbed-tls@lists.trustedfirmware.org Subject: [mbed-tls] PKCS#7 signedAttributes and embedded cert chain Hi, I recently had to do some PKCS#7 signature validation and was disappointed to find that it didn't just work. After digging through RFCs to figure out the myriad of things I'd done wrong I was also left with a lack of 3 features in mbedtls:
1. The full certificate chain was not being loaded and explicitly not supported. I believe this is in error since the certificate was never actually used anywhere, meaning it basically errored out for no reason. Since this certificate chain also contains the key used to validate the signature in my case that presented a pretty fundamental problem.
2. signedAttributes were not supported at all.
3. All the fields in mbedtls_pkcs7 and its associated structures are marked as MBEDTLS_PRIVATE. I need to inspect both the certificates and the signedAttributes and would rather not have to parse the entire DER myself.
I have attached patches implementing the first two. I believe I've done so without altering the behavior of the calls although I'm a bit unsure as to why mbedtls_x509_crt_verify doesn't take a const mbedtls_x509_crt. The third issue is a matter of policy and I don't know what your opinion on it is. For the moment I can at least get away with poking at the internal fields.
I have tested it on several signatures, one of which I have included here and I apologize in advance for the absolute spew but I thought it better than attaching even more files.
The data: 3059301306072A8648CE3D020106082A8648CE3D030107034200041B58AEE5B7C868AE0EED554133774B7C16802062EC2EB5A1A053318A9ED7DB943CE1F877671DADCFEB4D3171ACC2714ECBC0C0BCADE0569DF7CD0031623AF1BBDE72D8FFF60EC6D04B0D6C93658FC40F4AF2E22E1F68BF1A500FE00A94B804B7CA1DD7AF825C000FCF77A0ABB6918D2DF55C7A3CBC90BE14C59D8EE62A02B988DF7F32117770012AE362C03FB3AA3918AB9D10BE78442EFA7FCBA3CB02D6E196CE4137C6C3F280D963A5CD050EAC8871B3EB2C4500916FB3E39840D8EB198D58F49A434B2736385075BF9397405360B8694D0AD1E5DA8291F9EA47743F803F4A409EA72C2DF94F43DB60A0EAB8A8BD409C4D684200778B23D2A8126827995C3A80CAACA4AB7077266CED79BF91725330C9FCE3B8F1F5316C08C17B9994CF0ECB26D87A5C1F8FEB1FA737F78794895F6C5153B575EF8E95A8D433FD9486AA6C2B46ED6633D2BE0938202B99BEC21895018FB6FC59BAD662815A2C65200B8B1BAA4B69A8C89204B1EA70094026E9F710E599E14941476C8CD2E2879CF58E850DC732A506885F646BB9BE96B7A65355A6A9B907956E6DF65336504300CF062BA9DE50
It's SHA2-256 hash is: C76DE7AF191C16E01405CE8FE89136EB60AC035B3DDE34ACF65220AC7C3CA619
If you decode the signature DER you'll see a matching id-messageDigest in the signedAttributes towards the very bottom.
The signature in DER format: 3082089B06092A864886F70D010702A082088C30820888020101310D300B0609608648016503040201300B06092A864886F70D010701A08206D9308203E330820388A00302010202084C304149519D5436300A06082A8648CE3D040302307A312E302C06035504030C254170706C65204170706C69636174696F6E20496E746567726174696F6E204341202D20473331263024060355040B0C1D4170706C652043657274696669636174696F6E20417574686F7269747931133011060355040A0C0A4170706C6520496E632E310B3009060355040613025553301E170D3139303531383031333235375A170D3234303531363031333235375A305F3125302306035504030C1C6563632D736D702D62726F6B65722D7369676E5F5543342D50524F4431143012060355040B0C0B694F532053797374656D7331133011060355040A0C0A4170706C6520496E632E310B30090603550406130255533059301306072A8648CE3D020106082A8648CE3D03010703420004C21577EDEBD6C7B2218F68DD7090A1218DC7B0BD6F2C283D846095D94AF4A5411B83420ED811F3407E83331F1C54C3F7EB3220D6BAD5D4EFF49289893E7C0F13A38202113082020D300C0603551D130101FF04023000301F0603551D2304183016801423F249C44F93E4EF27E6C4F6286C3FA2BBFD2E4B304506 082B0601 050507010104393037303506082B060105050730018629687474703A2F2F6F6373702E6170706C652E636F6D2F6F63737030342D6170706C65616963613330323082011D0603551D2004820114308201103082010C06092A864886F7636405013081FE3081C306082B060105050702023081B60C81B352656C69616E6365206F6E207468697320636572746966696361746520627920616E7920706172747920617373756D657320616363657074616E6365206F6620746865207468656E206170706C696361626C65207374616E64617264207465726D7320616E6420636F6E646974696F6E73206F66207573652C20636572746966696361746520706F6C69637920616E642063657274696669636174696F6E2070726163746963652073746174656D656E74732E303606082B06010505070201162A687474703A2F2F7777772E6170706C652E636F6D2F6365727469666963617465617574686F726974792F30340603551D1F042D302B3029A027A0258623687474703A2F2F63726C2E6170706C652E636F6D2F6170706C6561696361332E63726C301D0603551D0E041604149457DB6FD57481868989762F7E578507E79B5824300E0603551D0F0101FF040403020780300F06092A864886F76364061D04020500300A06082A8648CE3D0403020349003046022100BE09571 FE71E1E7 35B55E5AFACB4C72FEB445F30185222C7251002B61EBD6F55022100D18B350A5DD6DD6EB1746035B11EB2CE87CFA3E6AF6CBD8380890DC82CDDAA63308202EE30820275A0030201020208496D2FBF3A98DA97300A06082A8648CE3D0403023067311B301906035504030C124170706C6520526F6F74204341202D20473331263024060355040B0C1D4170706C652043657274696669636174696F6E20417574686F7269747931133011060355040A0C0A4170706C6520496E632E310B3009060355040613025553301E170D3134303530363233343633305A170D3239303530363233343633305A307A312E302C06035504030C254170706C65204170706C69636174696F6E20496E746567726174696F6E204341202D20473331263024060355040B0C1D4170706C652043657274696669636174696F6E20417574686F7269747931133011060355040A0C0A4170706C6520496E632E310B30090603550406130255533059301306072A8648CE3D020106082A8648CE3D03010703420004F017118419D76485D51A5E25810776E880A2EFDE7BAE4DE08DFC4B93E13356D5665B35AE22D097760D224E7BBA08FD7617CE88CB76BB6670BEC8E82984FF5445A381F73081F4304606082B06010505070101043A3038303606082B06010505073001862A687474703A2F2F6F6373702E 6170706C 652E636F6D2F6F63737030342D6170706C65726F6F7463616733301D0603551D0E0416041423F249C44F93E4EF27E6C4F6286C3FA2BBFD2E4B300F0603551D130101FF040530030101FF301F0603551D23041830168014BBB0DEA15833889AA48A99DEBEBDEBAFDACB24AB30370603551D1F0430302E302CA02AA0288626687474703A2F2F63726C2E6170706C652E636F6D2F6170706C65726F6F74636167332E63726C300E0603551D0F0101FF0404030201063010060A2A864886F7636406020E04020500300A06082A8648CE3D040302036700306402303ACF7283511699B186FB35C356CA62BFF417EDD90F754DA28EBEF19C815E42B789F898F79B599F98D5410D8F9DE9C2FE0230322DD54421B0A305776C5DF3383B9067FD177C2C216D964FC6726982126F54F87A7D1B99CB9B0989216106990F09921D3182018830820184020101308186307A312E302C06035504030C254170706C65204170706C69636174696F6E20496E746567726174696F6E204341202D20473331263024060355040B0C1D4170706C652043657274696669636174696F6E20417574686F7269747931133011060355040A0C0A4170706C6520496E632E310B300906035504061302555302084C304149519D5436300B0609608648016503040201A08193301806092A864886F70D010903310B0 6092A864 886F70D010701301C06092A864886F70D010905310F170D3233303230393231333032345A302806092A864886F70D010934311B3019300B0609608648016503040201A10A06082A8648CE3D040302302F06092A864886F70D01090431220420C76DE7AF191C16E01405CE8FE89136EB60AC035B3DDE34ACF65220AC7C3CA619300A06082A8648CE3D04030204473045022100EE9B221CD9B5EEB1C6AF4160128D099C9414440A96C855A789846599E3BDE442022005AE51DC947E0B2AA6593E8FDB9F888782C71E5BB1CB6BF3C32B79C448C6A75D
Joakim
On Thu, 23 Feb 2023 14:23:05 +0000, Dave Rodgman via mbed-tls mbed-tls@lists.trustedfirmware.org wrote:
Hi Joakim,
The current PKCS #7 implementation indeed does not currently support certificate chains, and does not use a certificate from the PKCS #7 file to validate the signature, and does not support authenticatedAttributes.
We’ve tried to document these limitations clearly in include/mbedtls/pkcs7.h – if you think it’s not sufficiently clear, please raise an issue or PR with points for further improvement. We are currently tidying up the existing PKCS #7 functionality so want to get this right before the next release.
Sorry, I didn't mean to come of as flippant. It was actually just meant as an admission that things had generally just worked up until now so I hadn't done my due diligence.
Regarding use of MBEDTLS_PRIVATE – if there are particular fields that it’s useful to access, the preferred approach would probably be to add functions to the PKCS #7 API to access the fields in question, rather than remove MBEDTLS_PRIVATE.
I think it would be useful to grant access to the list of signers, the issuer name and the signedAttributes associated with each. I also think it would be good to give access to the list of certificates embedded in the signature. At the end of the day I just didn't want to step on anyones toes over it.
Thank you for providing these patches. Would you be able to submit them as a PR for review in the normal way via GitHub (see https://github.com/Mbed-TLS/mbedtls/blob/development/CONTRIBUTING.md for details)? They would also need some tests adding. If you don’t have time to work on these, I can create a PR but would need you to confirm that these submissions are made under the terms of our DCO.
I definitely don't have time in the near future, sorry, so I would appreciate it if you would take it from here.
The contribution was created in whole by me and I have the right to submit it under the open source license indicated in the file.
I understand and agree that this project and the contribution are public and that a record of the contribution (including all personal information I submit with it, including my sign-off) is maintained indefinitely and may be redistributed consistent with this project or the open source license(s) involved.
I hope that's clears it up.
Joakim
Joakim Sindholt wrote:
Sorry, I didn't mean to come of as flippant. It was actually just meant
as an admission that things had generally just worked up until now so I hadn't done my due diligence.
Not at all, we've already made a few improvements to the documentation but it's easy to overlook something that we think is "obvious". So someone fresh to the code highlighting these things is always helpful.
I definitely don't have time in the near future, sorry, so I would
appreciate it if you would take it from here.
Thanks for the contributions. I've created PRs here:
https://github.com/Mbed-TLS/mbedtls/pull/7159 https://github.com/Mbed-TLS/mbedtls/pull/7160
We'll need to find time (not sure when this might be) to fix the conflicts and add tests, but it's a useful starting point. If this is useful functionality for other people, please comment on the issue to highlight that would be useful, or feel free to adopt it and help out on getting it ready and reviewing it.
Dave thanks
Dave
mbed-tls@lists.trustedfirmware.org