diff options
author | orivej <orivej@yandex-team.ru> | 2022-02-10 16:45:01 +0300 |
---|---|---|
committer | Daniil Cherednik <dcherednik@yandex-team.ru> | 2022-02-10 16:45:01 +0300 |
commit | 2d37894b1b037cf24231090eda8589bbb44fb6fc (patch) | |
tree | be835aa92c6248212e705f25388ebafcf84bc7a1 /contrib/restricted/aws/aws-c-cal | |
parent | 718c552901d703c502ccbefdfc3c9028d608b947 (diff) | |
download | ydb-2d37894b1b037cf24231090eda8589bbb44fb6fc.tar.gz |
Restoring authorship annotation for <orivej@yandex-team.ru>. Commit 2 of 2.
Diffstat (limited to 'contrib/restricted/aws/aws-c-cal')
23 files changed, 3171 insertions, 3171 deletions
diff --git a/contrib/restricted/aws/aws-c-cal/CODE_OF_CONDUCT.md b/contrib/restricted/aws/aws-c-cal/CODE_OF_CONDUCT.md index 0f2daadff8..5b627cfa60 100644 --- a/contrib/restricted/aws/aws-c-cal/CODE_OF_CONDUCT.md +++ b/contrib/restricted/aws/aws-c-cal/CODE_OF_CONDUCT.md @@ -1,4 +1,4 @@ -## Code of Conduct -This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). -For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact -opensource-codeofconduct@amazon.com with any additional questions or comments. +## Code of Conduct +This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). +For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact +opensource-codeofconduct@amazon.com with any additional questions or comments. diff --git a/contrib/restricted/aws/aws-c-cal/CONTRIBUTING.md b/contrib/restricted/aws/aws-c-cal/CONTRIBUTING.md index df41e21bca..2b96875d0a 100644 --- a/contrib/restricted/aws/aws-c-cal/CONTRIBUTING.md +++ b/contrib/restricted/aws/aws-c-cal/CONTRIBUTING.md @@ -1,61 +1,61 @@ -# Contributing Guidelines - -Thank you for your interest in contributing to our project. Whether it's a bug report, new feature, correction, or additional -documentation, we greatly value feedback and contributions from our community. - -Please read through this document before submitting any issues or pull requests to ensure we have all the necessary -information to effectively respond to your bug report or contribution. - - -## Reporting Bugs/Feature Requests - -We welcome you to use the GitHub issue tracker to report bugs or suggest features. - -When filing an issue, please check [existing open](https://github.com/awslabs/aws-c-cal/issues), or [recently closed](https://github.com/awslabs/aws-c-cal/issues?utf8=%E2%9C%93&q=is%3Aissue%20is%3Aclosed%20), issues to make sure somebody else hasn't already -reported the issue. Please try to include as much information as you can. Details like these are incredibly useful: - -* A reproducible test case or series of steps -* The version of our code being used -* Any modifications you've made relevant to the bug -* Anything unusual about your environment or deployment - - -## Contributing via Pull Requests -Contributions via pull requests are much appreciated. Before sending us a pull request, please ensure that: - -1. You are working against the latest source on the *master* branch. -2. You check existing open, and recently merged, pull requests to make sure someone else hasn't addressed the problem already. -3. You open an issue to discuss any significant work - we would hate for your time to be wasted. - -To send us a pull request, please: - -1. Fork the repository. -2. Modify the source; please focus on the specific change you are contributing. If you also reformat all the code, it will be hard for us to focus on your change. -3. Ensure local tests pass. -4. Commit to your fork using clear commit messages. -5. Send us a pull request, answering any default questions in the pull request interface. -6. Pay attention to any automated CI failures reported in the pull request, and stay involved in the conversation. - -GitHub provides additional document on [forking a repository](https://help.github.com/articles/fork-a-repo/) and -[creating a pull request](https://help.github.com/articles/creating-a-pull-request/). - - -## Finding contributions to work on -Looking at the existing issues is a great way to find something to contribute on. As our projects, by default, use the default GitHub issue labels (enhancement/bug/duplicate/help wanted/invalid/question/wontfix), looking at any ['help wanted'](https://github.com/awslabs/aws-c-cal/labels/help%20wanted) issues is a great place to start. - - -## Code of Conduct -This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). -For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact -opensource-codeofconduct@amazon.com with any additional questions or comments. - - -## Security issue notifications -If you discover a potential security issue in this project we ask that you notify AWS/Amazon Security via our [vulnerability reporting page](http://aws.amazon.com/security/vulnerability-reporting/). Please do **not** create a public github issue. - - -## Licensing - -See the [LICENSE](https://github.com/awslabs/aws-c-cal/blob/master/LICENSE) file for our project's licensing. We will ask you to confirm the licensing of your contribution. - -We may ask you to sign a [Contributor License Agreement (CLA)](http://en.wikipedia.org/wiki/Contributor_License_Agreement) for larger changes. +# Contributing Guidelines + +Thank you for your interest in contributing to our project. Whether it's a bug report, new feature, correction, or additional +documentation, we greatly value feedback and contributions from our community. + +Please read through this document before submitting any issues or pull requests to ensure we have all the necessary +information to effectively respond to your bug report or contribution. + + +## Reporting Bugs/Feature Requests + +We welcome you to use the GitHub issue tracker to report bugs or suggest features. + +When filing an issue, please check [existing open](https://github.com/awslabs/aws-c-cal/issues), or [recently closed](https://github.com/awslabs/aws-c-cal/issues?utf8=%E2%9C%93&q=is%3Aissue%20is%3Aclosed%20), issues to make sure somebody else hasn't already +reported the issue. Please try to include as much information as you can. Details like these are incredibly useful: + +* A reproducible test case or series of steps +* The version of our code being used +* Any modifications you've made relevant to the bug +* Anything unusual about your environment or deployment + + +## Contributing via Pull Requests +Contributions via pull requests are much appreciated. Before sending us a pull request, please ensure that: + +1. You are working against the latest source on the *master* branch. +2. You check existing open, and recently merged, pull requests to make sure someone else hasn't addressed the problem already. +3. You open an issue to discuss any significant work - we would hate for your time to be wasted. + +To send us a pull request, please: + +1. Fork the repository. +2. Modify the source; please focus on the specific change you are contributing. If you also reformat all the code, it will be hard for us to focus on your change. +3. Ensure local tests pass. +4. Commit to your fork using clear commit messages. +5. Send us a pull request, answering any default questions in the pull request interface. +6. Pay attention to any automated CI failures reported in the pull request, and stay involved in the conversation. + +GitHub provides additional document on [forking a repository](https://help.github.com/articles/fork-a-repo/) and +[creating a pull request](https://help.github.com/articles/creating-a-pull-request/). + + +## Finding contributions to work on +Looking at the existing issues is a great way to find something to contribute on. As our projects, by default, use the default GitHub issue labels (enhancement/bug/duplicate/help wanted/invalid/question/wontfix), looking at any ['help wanted'](https://github.com/awslabs/aws-c-cal/labels/help%20wanted) issues is a great place to start. + + +## Code of Conduct +This project has adopted the [Amazon Open Source Code of Conduct](https://aws.github.io/code-of-conduct). +For more information see the [Code of Conduct FAQ](https://aws.github.io/code-of-conduct-faq) or contact +opensource-codeofconduct@amazon.com with any additional questions or comments. + + +## Security issue notifications +If you discover a potential security issue in this project we ask that you notify AWS/Amazon Security via our [vulnerability reporting page](http://aws.amazon.com/security/vulnerability-reporting/). Please do **not** create a public github issue. + + +## Licensing + +See the [LICENSE](https://github.com/awslabs/aws-c-cal/blob/master/LICENSE) file for our project's licensing. We will ask you to confirm the licensing of your contribution. + +We may ask you to sign a [Contributor License Agreement (CLA)](http://en.wikipedia.org/wiki/Contributor_License_Agreement) for larger changes. diff --git a/contrib/restricted/aws/aws-c-cal/LICENSE b/contrib/restricted/aws/aws-c-cal/LICENSE index a81c6e3602..67db858821 100644 --- a/contrib/restricted/aws/aws-c-cal/LICENSE +++ b/contrib/restricted/aws/aws-c-cal/LICENSE @@ -1,175 +1,175 @@ - - Apache License - Version 2.0, January 2004 - http://www.apache.org/licenses/ - - TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION - - 1. Definitions. - - "License" shall mean the terms and conditions for use, reproduction, - and distribution as defined by Sections 1 through 9 of this document. - - "Licensor" shall mean the copyright owner or entity authorized by - the copyright owner that is granting the License. - - "Legal Entity" shall mean the union of the acting entity and all - other entities that control, are controlled by, or are under common - control with that entity. For the purposes of this definition, - "control" means (i) the power, direct or indirect, to cause the - direction or management of such entity, whether by contract or - otherwise, or (ii) ownership of fifty percent (50%) or more of the - outstanding shares, or (iii) beneficial ownership of such entity. - - "You" (or "Your") shall mean an individual or Legal Entity - exercising permissions granted by this License. - - "Source" form shall mean the preferred form for making modifications, - including but not limited to software source code, documentation - source, and configuration files. - - "Object" form shall mean any form resulting from mechanical - transformation or translation of a Source form, including but - not limited to compiled object code, generated documentation, - and conversions to other media types. - - "Work" shall mean the work of authorship, whether in Source or - Object form, made available under the License, as indicated by a - copyright notice that is included in or attached to the work - (an example is provided in the Appendix below). - - "Derivative Works" shall mean any work, whether in Source or Object - form, that is based on (or derived from) the Work and for which the - editorial revisions, annotations, elaborations, or other modifications - represent, as a whole, an original work of authorship. For the purposes - of this License, Derivative Works shall not include works that remain - separable from, or merely link (or bind by name) to the interfaces of, - the Work and Derivative Works thereof. - - "Contribution" shall mean any work of authorship, including - the original version of the Work and any modifications or additions - to that Work or Derivative Works thereof, that is intentionally - submitted to Licensor for inclusion in the Work by the copyright owner - or by an individual or Legal Entity authorized to submit on behalf of - the copyright owner. For the purposes of this definition, "submitted" - means any form of electronic, verbal, or written communication sent - to the Licensor or its representatives, including but not limited to - communication on electronic mailing lists, source code control systems, - and issue tracking systems that are managed by, or on behalf of, the - Licensor for the purpose of discussing and improving the Work, but - excluding communication that is conspicuously marked or otherwise - designated in writing by the copyright owner as "Not a Contribution." - - "Contributor" shall mean Licensor and any individual or Legal Entity - on behalf of whom a Contribution has been received by Licensor and - subsequently incorporated within the Work. - - 2. Grant of Copyright License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - copyright license to reproduce, prepare Derivative Works of, - publicly display, publicly perform, sublicense, and distribute the - Work and such Derivative Works in Source or Object form. - - 3. Grant of Patent License. Subject to the terms and conditions of - this License, each Contributor hereby grants to You a perpetual, - worldwide, non-exclusive, no-charge, royalty-free, irrevocable - (except as stated in this section) patent license to make, have made, - use, offer to sell, sell, import, and otherwise transfer the Work, - where such license applies only to those patent claims licensable - by such Contributor that are necessarily infringed by their - Contribution(s) alone or by combination of their Contribution(s) - with the Work to which such Contribution(s) was submitted. If You - institute patent litigation against any entity (including a - cross-claim or counterclaim in a lawsuit) alleging that the Work - or a Contribution incorporated within the Work constitutes direct - or contributory patent infringement, then any patent licenses - granted to You under this License for that Work shall terminate - as of the date such litigation is filed. - - 4. Redistribution. You may reproduce and distribute copies of the - Work or Derivative Works thereof in any medium, with or without - modifications, and in Source or Object form, provided that You - meet the following conditions: - - (a) You must give any other recipients of the Work or - Derivative Works a copy of this License; and - - (b) You must cause any modified files to carry prominent notices - stating that You changed the files; and - - (c) You must retain, in the Source form of any Derivative Works - that You distribute, all copyright, patent, trademark, and - attribution notices from the Source form of the Work, - excluding those notices that do not pertain to any part of - the Derivative Works; and - - (d) If the Work includes a "NOTICE" text file as part of its - distribution, then any Derivative Works that You distribute must - include a readable copy of the attribution notices contained - within such NOTICE file, excluding those notices that do not - pertain to any part of the Derivative Works, in at least one - of the following places: within a NOTICE text file distributed - as part of the Derivative Works; within the Source form or - documentation, if provided along with the Derivative Works; or, - within a display generated by the Derivative Works, if and - wherever such third-party notices normally appear. The contents - of the NOTICE file are for informational purposes only and - do not modify the License. You may add Your own attribution - notices within Derivative Works that You distribute, alongside - or as an addendum to the NOTICE text from the Work, provided - that such additional attribution notices cannot be construed - as modifying the License. - - You may add Your own copyright statement to Your modifications and - may provide additional or different license terms and conditions - for use, reproduction, or distribution of Your modifications, or - for any such Derivative Works as a whole, provided Your use, - reproduction, and distribution of the Work otherwise complies with - the conditions stated in this License. - - 5. Submission of Contributions. Unless You explicitly state otherwise, - any Contribution intentionally submitted for inclusion in the Work - by You to the Licensor shall be under the terms and conditions of - this License, without any additional terms or conditions. - Notwithstanding the above, nothing herein shall supersede or modify - the terms of any separate license agreement you may have executed - with Licensor regarding such Contributions. - - 6. Trademarks. This License does not grant permission to use the trade - names, trademarks, service marks, or product names of the Licensor, - except as required for reasonable and customary use in describing the - origin of the Work and reproducing the content of the NOTICE file. - - 7. Disclaimer of Warranty. Unless required by applicable law or - agreed to in writing, Licensor provides the Work (and each - Contributor provides its Contributions) on an "AS IS" BASIS, - WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or - implied, including, without limitation, any warranties or conditions - of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A - PARTICULAR PURPOSE. You are solely responsible for determining the - appropriateness of using or redistributing the Work and assume any - risks associated with Your exercise of permissions under this License. - - 8. Limitation of Liability. In no event and under no legal theory, - whether in tort (including negligence), contract, or otherwise, - unless required by applicable law (such as deliberate and grossly - negligent acts) or agreed to in writing, shall any Contributor be - liable to You for damages, including any direct, indirect, special, - incidental, or consequential damages of any character arising as a - result of this License or out of the use or inability to use the - Work (including but not limited to damages for loss of goodwill, - work stoppage, computer failure or malfunction, or any and all - other commercial damages or losses), even if such Contributor - has been advised of the possibility of such damages. - - 9. Accepting Warranty or Additional Liability. While redistributing - the Work or Derivative Works thereof, You may choose to offer, - and charge a fee for, acceptance of support, warranty, indemnity, - or other liability obligations and/or rights consistent with this - License. However, in accepting such obligations, You may act only - on Your own behalf and on Your sole responsibility, not on behalf - of any other Contributor, and only if You agree to indemnify, - defend, and hold each Contributor harmless for any liability - incurred by, or claims asserted against, such Contributor by reason - of your accepting any such warranty or additional liability. + + Apache License + Version 2.0, January 2004 + http://www.apache.org/licenses/ + + TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION + + 1. Definitions. + + "License" shall mean the terms and conditions for use, reproduction, + and distribution as defined by Sections 1 through 9 of this document. + + "Licensor" shall mean the copyright owner or entity authorized by + the copyright owner that is granting the License. + + "Legal Entity" shall mean the union of the acting entity and all + other entities that control, are controlled by, or are under common + control with that entity. For the purposes of this definition, + "control" means (i) the power, direct or indirect, to cause the + direction or management of such entity, whether by contract or + otherwise, or (ii) ownership of fifty percent (50%) or more of the + outstanding shares, or (iii) beneficial ownership of such entity. + + "You" (or "Your") shall mean an individual or Legal Entity + exercising permissions granted by this License. + + "Source" form shall mean the preferred form for making modifications, + including but not limited to software source code, documentation + source, and configuration files. + + "Object" form shall mean any form resulting from mechanical + transformation or translation of a Source form, including but + not limited to compiled object code, generated documentation, + and conversions to other media types. + + "Work" shall mean the work of authorship, whether in Source or + Object form, made available under the License, as indicated by a + copyright notice that is included in or attached to the work + (an example is provided in the Appendix below). + + "Derivative Works" shall mean any work, whether in Source or Object + form, that is based on (or derived from) the Work and for which the + editorial revisions, annotations, elaborations, or other modifications + represent, as a whole, an original work of authorship. For the purposes + of this License, Derivative Works shall not include works that remain + separable from, or merely link (or bind by name) to the interfaces of, + the Work and Derivative Works thereof. + + "Contribution" shall mean any work of authorship, including + the original version of the Work and any modifications or additions + to that Work or Derivative Works thereof, that is intentionally + submitted to Licensor for inclusion in the Work by the copyright owner + or by an individual or Legal Entity authorized to submit on behalf of + the copyright owner. For the purposes of this definition, "submitted" + means any form of electronic, verbal, or written communication sent + to the Licensor or its representatives, including but not limited to + communication on electronic mailing lists, source code control systems, + and issue tracking systems that are managed by, or on behalf of, the + Licensor for the purpose of discussing and improving the Work, but + excluding communication that is conspicuously marked or otherwise + designated in writing by the copyright owner as "Not a Contribution." + + "Contributor" shall mean Licensor and any individual or Legal Entity + on behalf of whom a Contribution has been received by Licensor and + subsequently incorporated within the Work. + + 2. Grant of Copyright License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + copyright license to reproduce, prepare Derivative Works of, + publicly display, publicly perform, sublicense, and distribute the + Work and such Derivative Works in Source or Object form. + + 3. Grant of Patent License. Subject to the terms and conditions of + this License, each Contributor hereby grants to You a perpetual, + worldwide, non-exclusive, no-charge, royalty-free, irrevocable + (except as stated in this section) patent license to make, have made, + use, offer to sell, sell, import, and otherwise transfer the Work, + where such license applies only to those patent claims licensable + by such Contributor that are necessarily infringed by their + Contribution(s) alone or by combination of their Contribution(s) + with the Work to which such Contribution(s) was submitted. If You + institute patent litigation against any entity (including a + cross-claim or counterclaim in a lawsuit) alleging that the Work + or a Contribution incorporated within the Work constitutes direct + or contributory patent infringement, then any patent licenses + granted to You under this License for that Work shall terminate + as of the date such litigation is filed. + + 4. Redistribution. You may reproduce and distribute copies of the + Work or Derivative Works thereof in any medium, with or without + modifications, and in Source or Object form, provided that You + meet the following conditions: + + (a) You must give any other recipients of the Work or + Derivative Works a copy of this License; and + + (b) You must cause any modified files to carry prominent notices + stating that You changed the files; and + + (c) You must retain, in the Source form of any Derivative Works + that You distribute, all copyright, patent, trademark, and + attribution notices from the Source form of the Work, + excluding those notices that do not pertain to any part of + the Derivative Works; and + + (d) If the Work includes a "NOTICE" text file as part of its + distribution, then any Derivative Works that You distribute must + include a readable copy of the attribution notices contained + within such NOTICE file, excluding those notices that do not + pertain to any part of the Derivative Works, in at least one + of the following places: within a NOTICE text file distributed + as part of the Derivative Works; within the Source form or + documentation, if provided along with the Derivative Works; or, + within a display generated by the Derivative Works, if and + wherever such third-party notices normally appear. The contents + of the NOTICE file are for informational purposes only and + do not modify the License. You may add Your own attribution + notices within Derivative Works that You distribute, alongside + or as an addendum to the NOTICE text from the Work, provided + that such additional attribution notices cannot be construed + as modifying the License. + + You may add Your own copyright statement to Your modifications and + may provide additional or different license terms and conditions + for use, reproduction, or distribution of Your modifications, or + for any such Derivative Works as a whole, provided Your use, + reproduction, and distribution of the Work otherwise complies with + the conditions stated in this License. + + 5. Submission of Contributions. Unless You explicitly state otherwise, + any Contribution intentionally submitted for inclusion in the Work + by You to the Licensor shall be under the terms and conditions of + this License, without any additional terms or conditions. + Notwithstanding the above, nothing herein shall supersede or modify + the terms of any separate license agreement you may have executed + with Licensor regarding such Contributions. + + 6. Trademarks. This License does not grant permission to use the trade + names, trademarks, service marks, or product names of the Licensor, + except as required for reasonable and customary use in describing the + origin of the Work and reproducing the content of the NOTICE file. + + 7. Disclaimer of Warranty. Unless required by applicable law or + agreed to in writing, Licensor provides the Work (and each + Contributor provides its Contributions) on an "AS IS" BASIS, + WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or + implied, including, without limitation, any warranties or conditions + of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A + PARTICULAR PURPOSE. You are solely responsible for determining the + appropriateness of using or redistributing the Work and assume any + risks associated with Your exercise of permissions under this License. + + 8. Limitation of Liability. In no event and under no legal theory, + whether in tort (including negligence), contract, or otherwise, + unless required by applicable law (such as deliberate and grossly + negligent acts) or agreed to in writing, shall any Contributor be + liable to You for damages, including any direct, indirect, special, + incidental, or consequential damages of any character arising as a + result of this License or out of the use or inability to use the + Work (including but not limited to damages for loss of goodwill, + work stoppage, computer failure or malfunction, or any and all + other commercial damages or losses), even if such Contributor + has been advised of the possibility of such damages. + + 9. Accepting Warranty or Additional Liability. While redistributing + the Work or Derivative Works thereof, You may choose to offer, + and charge a fee for, acceptance of support, warranty, indemnity, + or other liability obligations and/or rights consistent with this + License. However, in accepting such obligations, You may act only + on Your own behalf and on Your sole responsibility, not on behalf + of any other Contributor, and only if You agree to indemnify, + defend, and hold each Contributor harmless for any liability + incurred by, or claims asserted against, such Contributor by reason + of your accepting any such warranty or additional liability. diff --git a/contrib/restricted/aws/aws-c-cal/NOTICE b/contrib/restricted/aws/aws-c-cal/NOTICE index 174f100068..df81ba71af 100644 --- a/contrib/restricted/aws/aws-c-cal/NOTICE +++ b/contrib/restricted/aws/aws-c-cal/NOTICE @@ -1,3 +1,3 @@ -AWS C Cal -Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. -SPDX-License-Identifier: Apache-2.0. +AWS C Cal +Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. +SPDX-License-Identifier: Apache-2.0. diff --git a/contrib/restricted/aws/aws-c-cal/README.md b/contrib/restricted/aws/aws-c-cal/README.md index de2ac340ab..78f2b8a919 100644 --- a/contrib/restricted/aws/aws-c-cal/README.md +++ b/contrib/restricted/aws/aws-c-cal/README.md @@ -1,91 +1,91 @@ -## AWS C Cal - -AWS Crypto Abstraction Layer: Cross-Platform, C99 wrapper for cryptography primitives. - -## License - -This library is licensed under the Apache 2.0 License. - -## Supported Platforms -* Windows (Vista and Later) -* Apple -* Unix (via OpenSSL compatible libcrypto) - -## Build Instructions -Since this project builds with CMake, you can build with whichever tool you prefer. Here, we show make for simplicity. You can -use Visual Studio, XCode, or whatever you'd like via the -G option. - -``` -git clone git@github.com:awslabs/aws-c-common -mkdir aws-c-common-build -cd aws-c-common-build -cmake -DCMAKE_PREFIX_PATH=<install path> -DCMAKE_INSTALL_PREFIX=<install path> ../aws-c-common -make -make test -make install - -cd .. -git clone git@github.com:awslabs/aws-c-cal -mkdir aws-c-cal-build -cd aws-c-cal-build -cmake -DCMAKE_PREFIX_PATH=<install path> -DCMAKE_INSTALL_PREFIX=<install path> ../aws-c-cal -make -make test -make install -```` - -## Currently provided algorithms - -### Hashes -#### MD5 -##### Streaming -```` -struct aws_hash *hash = aws_md5_new(allocator); -aws_hash_update(hash, &your_buffer); -aws_hash_finalize(hash, &output_buffer, 0); -aws_hash_destroy(hash); -```` - -##### One-Shot -```` -aws_md5_compute(allocator, &your_buffer, &output_buffer, 0); -```` - -#### SHA256 -##### Streaming -```` -struct aws_hash *hash = aws_sha256_new(allocator); -aws_hash_update(hash, &your_buffer); -aws_hash_finalize(hash, &output_buffer, 0); -aws_hash_destroy(hash); -```` - -##### One-Shot -```` -aws_sha256_compute(allocator, &your_buffer, &output_buffer, 0); -```` - -### HMAC -#### SHA256 HMAC -##### Streaming -```` -struct aws_hmac *hmac = aws_sha256_hmac_new(allocator, &secret_buf); -aws_hmac_update(hmac, &your_buffer); -aws_hmac_finalize(hmac, &output_buffer, 0); -aws_hmac_destroy(hmac); -```` - -##### One-Shot -```` -aws_sha256_hmac_compute(allocator, &secret_buf, &your_buffer, &output_buffer, 0); -```` - -## FAQ -### I want more algorithms, what do I do? -Great! So do we! At a minimum, file an issue letting us know. If you want to file a Pull Request, we'd be happy to review and merge it when it's ready. -### Who should consume this package directly? -Are you writing C directly? Then you should. -Are you using any other programming language? This functionality will be exposed via that language specific crt packages. -### I found a security vulnerability in this package. What do I do? -Due to the fact that this package is specifically performing cryptographic operations, please don't file a public issue. Instead, email aws-sdk-common-runtime@amazon.com, and we'll work with you directly. - +## AWS C Cal + +AWS Crypto Abstraction Layer: Cross-Platform, C99 wrapper for cryptography primitives. + +## License + +This library is licensed under the Apache 2.0 License. + +## Supported Platforms +* Windows (Vista and Later) +* Apple +* Unix (via OpenSSL compatible libcrypto) + +## Build Instructions +Since this project builds with CMake, you can build with whichever tool you prefer. Here, we show make for simplicity. You can +use Visual Studio, XCode, or whatever you'd like via the -G option. + +``` +git clone git@github.com:awslabs/aws-c-common +mkdir aws-c-common-build +cd aws-c-common-build +cmake -DCMAKE_PREFIX_PATH=<install path> -DCMAKE_INSTALL_PREFIX=<install path> ../aws-c-common +make +make test +make install + +cd .. +git clone git@github.com:awslabs/aws-c-cal +mkdir aws-c-cal-build +cd aws-c-cal-build +cmake -DCMAKE_PREFIX_PATH=<install path> -DCMAKE_INSTALL_PREFIX=<install path> ../aws-c-cal +make +make test +make install +```` + +## Currently provided algorithms + +### Hashes +#### MD5 +##### Streaming +```` +struct aws_hash *hash = aws_md5_new(allocator); +aws_hash_update(hash, &your_buffer); +aws_hash_finalize(hash, &output_buffer, 0); +aws_hash_destroy(hash); +```` + +##### One-Shot +```` +aws_md5_compute(allocator, &your_buffer, &output_buffer, 0); +```` + +#### SHA256 +##### Streaming +```` +struct aws_hash *hash = aws_sha256_new(allocator); +aws_hash_update(hash, &your_buffer); +aws_hash_finalize(hash, &output_buffer, 0); +aws_hash_destroy(hash); +```` + +##### One-Shot +```` +aws_sha256_compute(allocator, &your_buffer, &output_buffer, 0); +```` + +### HMAC +#### SHA256 HMAC +##### Streaming +```` +struct aws_hmac *hmac = aws_sha256_hmac_new(allocator, &secret_buf); +aws_hmac_update(hmac, &your_buffer); +aws_hmac_finalize(hmac, &output_buffer, 0); +aws_hmac_destroy(hmac); +```` + +##### One-Shot +```` +aws_sha256_hmac_compute(allocator, &secret_buf, &your_buffer, &output_buffer, 0); +```` + +## FAQ +### I want more algorithms, what do I do? +Great! So do we! At a minimum, file an issue letting us know. If you want to file a Pull Request, we'd be happy to review and merge it when it's ready. +### Who should consume this package directly? +Are you writing C directly? Then you should. +Are you using any other programming language? This functionality will be exposed via that language specific crt packages. +### I found a security vulnerability in this package. What do I do? +Due to the fact that this package is specifically performing cryptographic operations, please don't file a public issue. Instead, email aws-sdk-common-runtime@amazon.com, and we'll work with you directly. + diff --git a/contrib/restricted/aws/aws-c-cal/include/aws/cal/cal.h b/contrib/restricted/aws/aws-c-cal/include/aws/cal/cal.h index f266f18c4c..8c6986842b 100644 --- a/contrib/restricted/aws/aws-c-cal/include/aws/cal/cal.h +++ b/contrib/restricted/aws/aws-c-cal/include/aws/cal/cal.h @@ -1,35 +1,35 @@ -#ifndef AWS_CAL_CAL_H -#define AWS_CAL_CAL_H -/** - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0. - */ - -#include <aws/common/common.h> - -#include <aws/cal/exports.h> - -struct aws_allocator; - -#define AWS_C_CAL_PACKAGE_ID 7 - -enum aws_cal_errors { - AWS_ERROR_CAL_SIGNATURE_VALIDATION_FAILED = AWS_ERROR_ENUM_BEGIN_RANGE(AWS_C_CAL_PACKAGE_ID), - AWS_ERROR_CAL_MISSING_REQUIRED_KEY_COMPONENT, - AWS_ERROR_CAL_INVALID_KEY_LENGTH_FOR_ALGORITHM, - AWS_ERROR_CAL_UNKNOWN_OBJECT_IDENTIFIER, - AWS_ERROR_CAL_MALFORMED_ASN1_ENCOUNTERED, - AWS_ERROR_CAL_MISMATCHED_DER_TYPE, - AWS_ERROR_CAL_UNSUPPORTED_ALGORITHM, - - AWS_ERROR_CAL_END_RANGE = AWS_ERROR_ENUM_END_RANGE(AWS_C_CAL_PACKAGE_ID) -}; - -AWS_EXTERN_C_BEGIN - -AWS_CAL_API void aws_cal_library_init(struct aws_allocator *allocator); -AWS_CAL_API void aws_cal_library_clean_up(void); - -AWS_EXTERN_C_END - -#endif /* AWS_CAL_CAL_H */ +#ifndef AWS_CAL_CAL_H +#define AWS_CAL_CAL_H +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#include <aws/common/common.h> + +#include <aws/cal/exports.h> + +struct aws_allocator; + +#define AWS_C_CAL_PACKAGE_ID 7 + +enum aws_cal_errors { + AWS_ERROR_CAL_SIGNATURE_VALIDATION_FAILED = AWS_ERROR_ENUM_BEGIN_RANGE(AWS_C_CAL_PACKAGE_ID), + AWS_ERROR_CAL_MISSING_REQUIRED_KEY_COMPONENT, + AWS_ERROR_CAL_INVALID_KEY_LENGTH_FOR_ALGORITHM, + AWS_ERROR_CAL_UNKNOWN_OBJECT_IDENTIFIER, + AWS_ERROR_CAL_MALFORMED_ASN1_ENCOUNTERED, + AWS_ERROR_CAL_MISMATCHED_DER_TYPE, + AWS_ERROR_CAL_UNSUPPORTED_ALGORITHM, + + AWS_ERROR_CAL_END_RANGE = AWS_ERROR_ENUM_END_RANGE(AWS_C_CAL_PACKAGE_ID) +}; + +AWS_EXTERN_C_BEGIN + +AWS_CAL_API void aws_cal_library_init(struct aws_allocator *allocator); +AWS_CAL_API void aws_cal_library_clean_up(void); + +AWS_EXTERN_C_END + +#endif /* AWS_CAL_CAL_H */ diff --git a/contrib/restricted/aws/aws-c-cal/include/aws/cal/ecc.h b/contrib/restricted/aws/aws-c-cal/include/aws/cal/ecc.h index 36e5f90b09..660c26d79b 100644 --- a/contrib/restricted/aws/aws-c-cal/include/aws/cal/ecc.h +++ b/contrib/restricted/aws/aws-c-cal/include/aws/cal/ecc.h @@ -1,177 +1,177 @@ -#ifndef AWS_CAL_ECC_H -#define AWS_CAL_ECC_H -/** - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0. - */ -#include <aws/cal/exports.h> - -#include <aws/common/atomics.h> -#include <aws/common/byte_buf.h> -#include <aws/common/common.h> - -enum aws_ecc_curve_name { - AWS_CAL_ECDSA_P256, - AWS_CAL_ECDSA_P384, -}; - -struct aws_ecc_key_pair; - -typedef void aws_ecc_key_pair_destroy_fn(struct aws_ecc_key_pair *key_pair); -typedef int aws_ecc_key_pair_sign_message_fn( - const struct aws_ecc_key_pair *key_pair, - const struct aws_byte_cursor *message, - struct aws_byte_buf *signature_output); -typedef int aws_ecc_key_pair_derive_public_key_fn(struct aws_ecc_key_pair *key_pair); -typedef int aws_ecc_key_pair_verify_signature_fn( - const struct aws_ecc_key_pair *signer, - const struct aws_byte_cursor *message, - const struct aws_byte_cursor *signature); -typedef size_t aws_ecc_key_pair_signature_length_fn(const struct aws_ecc_key_pair *signer); - -struct aws_ecc_key_pair_vtable { - aws_ecc_key_pair_destroy_fn *destroy; - aws_ecc_key_pair_derive_public_key_fn *derive_pub_key; - aws_ecc_key_pair_sign_message_fn *sign_message; - aws_ecc_key_pair_verify_signature_fn *verify_signature; - aws_ecc_key_pair_signature_length_fn *signature_length; -}; - -struct aws_ecc_key_pair { - struct aws_allocator *allocator; - struct aws_atomic_var ref_count; - enum aws_ecc_curve_name curve_name; - struct aws_byte_buf key_buf; - struct aws_byte_buf pub_x; - struct aws_byte_buf pub_y; - struct aws_byte_buf priv_d; - struct aws_ecc_key_pair_vtable *vtable; - void *impl; -}; - -AWS_EXTERN_C_BEGIN - -/** - * Adds one to an ecc key pair's ref count. - */ -AWS_CAL_API void aws_ecc_key_pair_acquire(struct aws_ecc_key_pair *key_pair); - -/** - * Subtracts one from an ecc key pair's ref count. If ref count reaches zero, the key pair is destroyed. - */ -AWS_CAL_API void aws_ecc_key_pair_release(struct aws_ecc_key_pair *key_pair); - -/** - * Creates a Eliptic Curve private key that can be used for signing. - * Returns a new instance of aws_ecc_key_pair if the key was successfully built. - * Otherwise returns NULL. Note: priv_key::len must match the appropriate length - * for the selected curve_name. - */ -AWS_CAL_API struct aws_ecc_key_pair *aws_ecc_key_pair_new_from_private_key( - struct aws_allocator *allocator, - enum aws_ecc_curve_name curve_name, - const struct aws_byte_cursor *priv_key); - -#if !defined(AWS_OS_IOS) -/** - * Creates a Eliptic Curve public/private key pair that can be used for signing and verifying. - * Returns a new instance of aws_ecc_key_pair if the key was successfully built. - * Otherwise returns NULL. - */ -AWS_CAL_API struct aws_ecc_key_pair *aws_ecc_key_pair_new_generate_random( - struct aws_allocator *allocator, - enum aws_ecc_curve_name curve_name); -#endif /* !AWS_OS_IOS */ - -/** - * Creates a Eliptic Curve public key that can be used for verifying. - * Returns a new instance of aws_ecc_key_pair if the key was successfully built. - * Otherwise returns NULL. Note: public_key_x::len and public_key_y::len must - * match the appropriate length for the selected curve_name. - */ -AWS_CAL_API struct aws_ecc_key_pair *aws_ecc_key_pair_new_from_public_key( - struct aws_allocator *allocator, - enum aws_ecc_curve_name curve_name, - const struct aws_byte_cursor *public_key_x, - const struct aws_byte_cursor *public_key_y); - -/** - * Creates a Eliptic Curve public/private key pair from a DER encoded key pair. - * Returns a new instance of aws_ecc_key_pair if the key was successfully built. - * Otherwise returns NULL. Whether or not signing or verification can be perform depends - * on if encoded_keys is a public/private pair or a public key. - */ -AWS_CAL_API struct aws_ecc_key_pair *aws_ecc_key_pair_new_from_asn1( - struct aws_allocator *allocator, - const struct aws_byte_cursor *encoded_keys); - -/** - * Creates an Elliptic curve public key from x and y coordinates encoded as hex strings - * Returns a new instance of aws_ecc_key_pair if the key was successfully built. - * Otherwise returns NULL. - */ -AWS_CAL_API struct aws_ecc_key_pair *aws_ecc_key_new_from_hex_coordinates( - struct aws_allocator *allocator, - enum aws_ecc_curve_name curve_name, - struct aws_byte_cursor pub_x_hex_cursor, - struct aws_byte_cursor pub_y_hex_cursor); - -/** - * Derives a public key from the private key if supported by this operating system (not supported on OSX). - * key_pair::pub_x and key_pair::pub_y will be set with the raw key buffers. - */ -AWS_CAL_API int aws_ecc_key_pair_derive_public_key(struct aws_ecc_key_pair *key_pair); - -/** - * Get the curve name from the oid. OID here is the payload of the DER encoded ASN.1 part (doesn't include - * type specifier or length. On success, the value of curve_name will be set. - */ -AWS_CAL_API int aws_ecc_curve_name_from_oid(struct aws_byte_cursor *oid, enum aws_ecc_curve_name *curve_name); - -/** - * Get the DER encoded OID from the curve_name. The OID in this case will not contain the type or the length specifier. - */ -AWS_CAL_API int aws_ecc_oid_from_curve_name(enum aws_ecc_curve_name curve_name, struct aws_byte_cursor *oid); - -/** - * Uses the key_pair's private key to sign message. The output will be in signature. Signature must be large enough - * to hold the signature. Check aws_ecc_key_pair_signature_length() for the appropriate size. Signature will be DER - * encoded. - * - * It is the callers job to make sure message is the appropriate cryptographic digest for this operation. It's usually - * something like a SHA256. - */ -AWS_CAL_API int aws_ecc_key_pair_sign_message( - const struct aws_ecc_key_pair *key_pair, - const struct aws_byte_cursor *message, - struct aws_byte_buf *signature); - -/** - * Uses the key_pair's public key to verify signature of message. Signature should be DER - * encoded. - * - * It is the callers job to make sure message is the appropriate cryptographic digest for this operation. It's usually - * something like a SHA256. - * - * returns AWS_OP_SUCCESS if the signature is valid. - */ -AWS_CAL_API int aws_ecc_key_pair_verify_signature( - const struct aws_ecc_key_pair *key_pair, - const struct aws_byte_cursor *message, - const struct aws_byte_cursor *signature); -AWS_CAL_API size_t aws_ecc_key_pair_signature_length(const struct aws_ecc_key_pair *key_pair); - -AWS_CAL_API void aws_ecc_key_pair_get_public_key( - const struct aws_ecc_key_pair *key_pair, - struct aws_byte_cursor *pub_x, - struct aws_byte_cursor *pub_y); - -AWS_CAL_API void aws_ecc_key_pair_get_private_key( - const struct aws_ecc_key_pair *key_pair, - struct aws_byte_cursor *private_d); - -AWS_CAL_API size_t aws_ecc_key_coordinate_byte_size_from_curve_name(enum aws_ecc_curve_name curve_name); - -AWS_EXTERN_C_END - -#endif /* AWS_CAL_ECC_H */ +#ifndef AWS_CAL_ECC_H +#define AWS_CAL_ECC_H +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ +#include <aws/cal/exports.h> + +#include <aws/common/atomics.h> +#include <aws/common/byte_buf.h> +#include <aws/common/common.h> + +enum aws_ecc_curve_name { + AWS_CAL_ECDSA_P256, + AWS_CAL_ECDSA_P384, +}; + +struct aws_ecc_key_pair; + +typedef void aws_ecc_key_pair_destroy_fn(struct aws_ecc_key_pair *key_pair); +typedef int aws_ecc_key_pair_sign_message_fn( + const struct aws_ecc_key_pair *key_pair, + const struct aws_byte_cursor *message, + struct aws_byte_buf *signature_output); +typedef int aws_ecc_key_pair_derive_public_key_fn(struct aws_ecc_key_pair *key_pair); +typedef int aws_ecc_key_pair_verify_signature_fn( + const struct aws_ecc_key_pair *signer, + const struct aws_byte_cursor *message, + const struct aws_byte_cursor *signature); +typedef size_t aws_ecc_key_pair_signature_length_fn(const struct aws_ecc_key_pair *signer); + +struct aws_ecc_key_pair_vtable { + aws_ecc_key_pair_destroy_fn *destroy; + aws_ecc_key_pair_derive_public_key_fn *derive_pub_key; + aws_ecc_key_pair_sign_message_fn *sign_message; + aws_ecc_key_pair_verify_signature_fn *verify_signature; + aws_ecc_key_pair_signature_length_fn *signature_length; +}; + +struct aws_ecc_key_pair { + struct aws_allocator *allocator; + struct aws_atomic_var ref_count; + enum aws_ecc_curve_name curve_name; + struct aws_byte_buf key_buf; + struct aws_byte_buf pub_x; + struct aws_byte_buf pub_y; + struct aws_byte_buf priv_d; + struct aws_ecc_key_pair_vtable *vtable; + void *impl; +}; + +AWS_EXTERN_C_BEGIN + +/** + * Adds one to an ecc key pair's ref count. + */ +AWS_CAL_API void aws_ecc_key_pair_acquire(struct aws_ecc_key_pair *key_pair); + +/** + * Subtracts one from an ecc key pair's ref count. If ref count reaches zero, the key pair is destroyed. + */ +AWS_CAL_API void aws_ecc_key_pair_release(struct aws_ecc_key_pair *key_pair); + +/** + * Creates a Eliptic Curve private key that can be used for signing. + * Returns a new instance of aws_ecc_key_pair if the key was successfully built. + * Otherwise returns NULL. Note: priv_key::len must match the appropriate length + * for the selected curve_name. + */ +AWS_CAL_API struct aws_ecc_key_pair *aws_ecc_key_pair_new_from_private_key( + struct aws_allocator *allocator, + enum aws_ecc_curve_name curve_name, + const struct aws_byte_cursor *priv_key); + +#if !defined(AWS_OS_IOS) +/** + * Creates a Eliptic Curve public/private key pair that can be used for signing and verifying. + * Returns a new instance of aws_ecc_key_pair if the key was successfully built. + * Otherwise returns NULL. + */ +AWS_CAL_API struct aws_ecc_key_pair *aws_ecc_key_pair_new_generate_random( + struct aws_allocator *allocator, + enum aws_ecc_curve_name curve_name); +#endif /* !AWS_OS_IOS */ + +/** + * Creates a Eliptic Curve public key that can be used for verifying. + * Returns a new instance of aws_ecc_key_pair if the key was successfully built. + * Otherwise returns NULL. Note: public_key_x::len and public_key_y::len must + * match the appropriate length for the selected curve_name. + */ +AWS_CAL_API struct aws_ecc_key_pair *aws_ecc_key_pair_new_from_public_key( + struct aws_allocator *allocator, + enum aws_ecc_curve_name curve_name, + const struct aws_byte_cursor *public_key_x, + const struct aws_byte_cursor *public_key_y); + +/** + * Creates a Eliptic Curve public/private key pair from a DER encoded key pair. + * Returns a new instance of aws_ecc_key_pair if the key was successfully built. + * Otherwise returns NULL. Whether or not signing or verification can be perform depends + * on if encoded_keys is a public/private pair or a public key. + */ +AWS_CAL_API struct aws_ecc_key_pair *aws_ecc_key_pair_new_from_asn1( + struct aws_allocator *allocator, + const struct aws_byte_cursor *encoded_keys); + +/** + * Creates an Elliptic curve public key from x and y coordinates encoded as hex strings + * Returns a new instance of aws_ecc_key_pair if the key was successfully built. + * Otherwise returns NULL. + */ +AWS_CAL_API struct aws_ecc_key_pair *aws_ecc_key_new_from_hex_coordinates( + struct aws_allocator *allocator, + enum aws_ecc_curve_name curve_name, + struct aws_byte_cursor pub_x_hex_cursor, + struct aws_byte_cursor pub_y_hex_cursor); + +/** + * Derives a public key from the private key if supported by this operating system (not supported on OSX). + * key_pair::pub_x and key_pair::pub_y will be set with the raw key buffers. + */ +AWS_CAL_API int aws_ecc_key_pair_derive_public_key(struct aws_ecc_key_pair *key_pair); + +/** + * Get the curve name from the oid. OID here is the payload of the DER encoded ASN.1 part (doesn't include + * type specifier or length. On success, the value of curve_name will be set. + */ +AWS_CAL_API int aws_ecc_curve_name_from_oid(struct aws_byte_cursor *oid, enum aws_ecc_curve_name *curve_name); + +/** + * Get the DER encoded OID from the curve_name. The OID in this case will not contain the type or the length specifier. + */ +AWS_CAL_API int aws_ecc_oid_from_curve_name(enum aws_ecc_curve_name curve_name, struct aws_byte_cursor *oid); + +/** + * Uses the key_pair's private key to sign message. The output will be in signature. Signature must be large enough + * to hold the signature. Check aws_ecc_key_pair_signature_length() for the appropriate size. Signature will be DER + * encoded. + * + * It is the callers job to make sure message is the appropriate cryptographic digest for this operation. It's usually + * something like a SHA256. + */ +AWS_CAL_API int aws_ecc_key_pair_sign_message( + const struct aws_ecc_key_pair *key_pair, + const struct aws_byte_cursor *message, + struct aws_byte_buf *signature); + +/** + * Uses the key_pair's public key to verify signature of message. Signature should be DER + * encoded. + * + * It is the callers job to make sure message is the appropriate cryptographic digest for this operation. It's usually + * something like a SHA256. + * + * returns AWS_OP_SUCCESS if the signature is valid. + */ +AWS_CAL_API int aws_ecc_key_pair_verify_signature( + const struct aws_ecc_key_pair *key_pair, + const struct aws_byte_cursor *message, + const struct aws_byte_cursor *signature); +AWS_CAL_API size_t aws_ecc_key_pair_signature_length(const struct aws_ecc_key_pair *key_pair); + +AWS_CAL_API void aws_ecc_key_pair_get_public_key( + const struct aws_ecc_key_pair *key_pair, + struct aws_byte_cursor *pub_x, + struct aws_byte_cursor *pub_y); + +AWS_CAL_API void aws_ecc_key_pair_get_private_key( + const struct aws_ecc_key_pair *key_pair, + struct aws_byte_cursor *private_d); + +AWS_CAL_API size_t aws_ecc_key_coordinate_byte_size_from_curve_name(enum aws_ecc_curve_name curve_name); + +AWS_EXTERN_C_END + +#endif /* AWS_CAL_ECC_H */ diff --git a/contrib/restricted/aws/aws-c-cal/include/aws/cal/exports.h b/contrib/restricted/aws/aws-c-cal/include/aws/cal/exports.h index c73f19974c..d6ab9734b7 100644 --- a/contrib/restricted/aws/aws-c-cal/include/aws/cal/exports.h +++ b/contrib/restricted/aws/aws-c-cal/include/aws/cal/exports.h @@ -1,28 +1,28 @@ -#ifndef AWS_CAL_EXPORTS_H -#define AWS_CAL_EXPORTS_H -/** - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0. - */ -#if defined(AWS_C_RT_USE_WINDOWS_DLL_SEMANTICS) || defined(WIN32) -# ifdef AWS_CAL_USE_IMPORT_EXPORT -# ifdef AWS_CAL_EXPORTS -# define AWS_CAL_API __declspec(dllexport) -# else -# define AWS_CAL_API __declspec(dllimport) -# endif /* AWS_CAL_EXPORTS */ -# else -# define AWS_CAL_API -# endif /* AWS_CAL_USE_IMPORT_EXPORT */ - -#else /* defined (AWS_C_RT_USE_WINDOWS_DLL_SEMANTICS) || defined (WIN32) */ - -# if ((__GNUC__ >= 4) || defined(__clang__)) && defined(AWS_CAL_USE_IMPORT_EXPORT) && defined(AWS_CAL_EXPORTS) -# define AWS_CAL_API __attribute__((visibility("default"))) -# else -# define AWS_CAL_API -# endif /* __GNUC__ >= 4 || defined(__clang__) */ - -#endif /* defined (AWS_C_RT_USE_WINDOWS_DLL_SEMANTICS) || defined (WIN32) */ - -#endif /* AWS_CAL_EXPORTS_H */ +#ifndef AWS_CAL_EXPORTS_H +#define AWS_CAL_EXPORTS_H +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ +#if defined(AWS_C_RT_USE_WINDOWS_DLL_SEMANTICS) || defined(WIN32) +# ifdef AWS_CAL_USE_IMPORT_EXPORT +# ifdef AWS_CAL_EXPORTS +# define AWS_CAL_API __declspec(dllexport) +# else +# define AWS_CAL_API __declspec(dllimport) +# endif /* AWS_CAL_EXPORTS */ +# else +# define AWS_CAL_API +# endif /* AWS_CAL_USE_IMPORT_EXPORT */ + +#else /* defined (AWS_C_RT_USE_WINDOWS_DLL_SEMANTICS) || defined (WIN32) */ + +# if ((__GNUC__ >= 4) || defined(__clang__)) && defined(AWS_CAL_USE_IMPORT_EXPORT) && defined(AWS_CAL_EXPORTS) +# define AWS_CAL_API __attribute__((visibility("default"))) +# else +# define AWS_CAL_API +# endif /* __GNUC__ >= 4 || defined(__clang__) */ + +#endif /* defined (AWS_C_RT_USE_WINDOWS_DLL_SEMANTICS) || defined (WIN32) */ + +#endif /* AWS_CAL_EXPORTS_H */ diff --git a/contrib/restricted/aws/aws-c-cal/include/aws/cal/hash.h b/contrib/restricted/aws/aws-c-cal/include/aws/cal/hash.h index 865a12f756..ebf70e39e4 100644 --- a/contrib/restricted/aws/aws-c-cal/include/aws/cal/hash.h +++ b/contrib/restricted/aws/aws-c-cal/include/aws/cal/hash.h @@ -1,107 +1,107 @@ -#ifndef AWS_CAL_HASH_H_ -#define AWS_CAL_HASH_H_ -/** - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0. - */ -#include <aws/cal/exports.h> - -#include <aws/common/byte_buf.h> -#include <aws/common/common.h> - -#define AWS_SHA256_LEN 32 -#define AWS_MD5_LEN 16 - -struct aws_hash; - -struct aws_hash_vtable { - const char *alg_name; - const char *provider; - void (*destroy)(struct aws_hash *hash); - int (*update)(struct aws_hash *hash, const struct aws_byte_cursor *buf); - int (*finalize)(struct aws_hash *hash, struct aws_byte_buf *out); -}; - -struct aws_hash { - struct aws_allocator *allocator; - struct aws_hash_vtable *vtable; - size_t digest_size; - bool good; - void *impl; -}; - -typedef struct aws_hash *(aws_hash_new_fn)(struct aws_allocator *allocator); - -AWS_EXTERN_C_BEGIN -/** - * Allocates and initializes a sha256 hash instance. - */ -AWS_CAL_API struct aws_hash *aws_sha256_new(struct aws_allocator *allocator); -/** - * Allocates and initializes an md5 hash instance. - */ -AWS_CAL_API struct aws_hash *aws_md5_new(struct aws_allocator *allocator); -/** - * Cleans up and deallocates hash. - */ -AWS_CAL_API void aws_hash_destroy(struct aws_hash *hash); -/** - * Updates the running hash with to_hash. this can be called multiple times. - */ -AWS_CAL_API int aws_hash_update(struct aws_hash *hash, const struct aws_byte_cursor *to_hash); -/** - * Completes the hash computation and writes the final digest to output. - * Allocation of output is the caller's responsibility. If you specify - * truncate_to to something other than 0, the output will be truncated to that - * number of bytes. For example if you want a SHA256 digest as the first 16 - * bytes, set truncate_to to 16. If you want the full digest size, just set this - * to 0. - */ -AWS_CAL_API int aws_hash_finalize(struct aws_hash *hash, struct aws_byte_buf *output, size_t truncate_to); - -/** - * Computes the md5 hash over input and writes the digest output to 'output'. - * Use this if you don't need to stream the data you're hashing and you can load - * the entire input to hash into memory. - */ -AWS_CAL_API int aws_md5_compute( - struct aws_allocator *allocator, - const struct aws_byte_cursor *input, - struct aws_byte_buf *output, - size_t truncate_to); - -/** - * Computes the sha256 hash over input and writes the digest output to 'output'. - * Use this if you don't need to stream the data you're hashing and you can load - * the entire input to hash into memory. If you specify truncate_to to something - * other than 0, the output will be truncated to that number of bytes. For - * example if you want a SHA256 digest as the first 16 bytes, set truncate_to - * to 16. If you want the full digest size, just set this to 0. - */ -AWS_CAL_API int aws_sha256_compute( - struct aws_allocator *allocator, - const struct aws_byte_cursor *input, - struct aws_byte_buf *output, - size_t truncate_to); - -/** - * Set the implementation of md5 to use. If you compiled without AWS_BYO_CRYPTO, - * you do not need to call this. However, if use this, we will honor it, - * regardless of compile options. This may be useful for testing purposes. If - * you did set AWS_BYO_CRYPTO, and you do not call this function you will - * segfault. - */ -AWS_CAL_API void aws_set_md5_new_fn(aws_hash_new_fn *fn); - -/** - * Set the implementation of sha256 to use. If you compiled without - * AWS_BYO_CRYPTO, you do not need to call this. However, if use this, we will - * honor it, regardless of compile options. This may be useful for testing - * purposes. If you did set AWS_BYO_CRYPTO, and you do not call this function - * you will segfault. - */ -AWS_CAL_API void aws_set_sha256_new_fn(aws_hash_new_fn *fn); - -AWS_EXTERN_C_END - -#endif /* AWS_CAL_HASH_H_ */ +#ifndef AWS_CAL_HASH_H_ +#define AWS_CAL_HASH_H_ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ +#include <aws/cal/exports.h> + +#include <aws/common/byte_buf.h> +#include <aws/common/common.h> + +#define AWS_SHA256_LEN 32 +#define AWS_MD5_LEN 16 + +struct aws_hash; + +struct aws_hash_vtable { + const char *alg_name; + const char *provider; + void (*destroy)(struct aws_hash *hash); + int (*update)(struct aws_hash *hash, const struct aws_byte_cursor *buf); + int (*finalize)(struct aws_hash *hash, struct aws_byte_buf *out); +}; + +struct aws_hash { + struct aws_allocator *allocator; + struct aws_hash_vtable *vtable; + size_t digest_size; + bool good; + void *impl; +}; + +typedef struct aws_hash *(aws_hash_new_fn)(struct aws_allocator *allocator); + +AWS_EXTERN_C_BEGIN +/** + * Allocates and initializes a sha256 hash instance. + */ +AWS_CAL_API struct aws_hash *aws_sha256_new(struct aws_allocator *allocator); +/** + * Allocates and initializes an md5 hash instance. + */ +AWS_CAL_API struct aws_hash *aws_md5_new(struct aws_allocator *allocator); +/** + * Cleans up and deallocates hash. + */ +AWS_CAL_API void aws_hash_destroy(struct aws_hash *hash); +/** + * Updates the running hash with to_hash. this can be called multiple times. + */ +AWS_CAL_API int aws_hash_update(struct aws_hash *hash, const struct aws_byte_cursor *to_hash); +/** + * Completes the hash computation and writes the final digest to output. + * Allocation of output is the caller's responsibility. If you specify + * truncate_to to something other than 0, the output will be truncated to that + * number of bytes. For example if you want a SHA256 digest as the first 16 + * bytes, set truncate_to to 16. If you want the full digest size, just set this + * to 0. + */ +AWS_CAL_API int aws_hash_finalize(struct aws_hash *hash, struct aws_byte_buf *output, size_t truncate_to); + +/** + * Computes the md5 hash over input and writes the digest output to 'output'. + * Use this if you don't need to stream the data you're hashing and you can load + * the entire input to hash into memory. + */ +AWS_CAL_API int aws_md5_compute( + struct aws_allocator *allocator, + const struct aws_byte_cursor *input, + struct aws_byte_buf *output, + size_t truncate_to); + +/** + * Computes the sha256 hash over input and writes the digest output to 'output'. + * Use this if you don't need to stream the data you're hashing and you can load + * the entire input to hash into memory. If you specify truncate_to to something + * other than 0, the output will be truncated to that number of bytes. For + * example if you want a SHA256 digest as the first 16 bytes, set truncate_to + * to 16. If you want the full digest size, just set this to 0. + */ +AWS_CAL_API int aws_sha256_compute( + struct aws_allocator *allocator, + const struct aws_byte_cursor *input, + struct aws_byte_buf *output, + size_t truncate_to); + +/** + * Set the implementation of md5 to use. If you compiled without AWS_BYO_CRYPTO, + * you do not need to call this. However, if use this, we will honor it, + * regardless of compile options. This may be useful for testing purposes. If + * you did set AWS_BYO_CRYPTO, and you do not call this function you will + * segfault. + */ +AWS_CAL_API void aws_set_md5_new_fn(aws_hash_new_fn *fn); + +/** + * Set the implementation of sha256 to use. If you compiled without + * AWS_BYO_CRYPTO, you do not need to call this. However, if use this, we will + * honor it, regardless of compile options. This may be useful for testing + * purposes. If you did set AWS_BYO_CRYPTO, and you do not call this function + * you will segfault. + */ +AWS_CAL_API void aws_set_sha256_new_fn(aws_hash_new_fn *fn); + +AWS_EXTERN_C_END + +#endif /* AWS_CAL_HASH_H_ */ diff --git a/contrib/restricted/aws/aws-c-cal/include/aws/cal/hmac.h b/contrib/restricted/aws/aws-c-cal/include/aws/cal/hmac.h index 37ce7cdc22..42183887d6 100644 --- a/contrib/restricted/aws/aws-c-cal/include/aws/cal/hmac.h +++ b/contrib/restricted/aws/aws-c-cal/include/aws/cal/hmac.h @@ -1,84 +1,84 @@ -#ifndef AWS_CAL_HMAC_H_ -#define AWS_CAL_HMAC_H_ -/** - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0. - */ -#include <aws/cal/exports.h> - -#include <aws/common/byte_buf.h> -#include <aws/common/common.h> - -#define AWS_SHA256_HMAC_LEN 32 - -struct aws_hmac; - -struct aws_hmac_vtable { - const char *alg_name; - const char *provider; - void (*destroy)(struct aws_hmac *hmac); - int (*update)(struct aws_hmac *hmac, const struct aws_byte_cursor *buf); - int (*finalize)(struct aws_hmac *hmac, struct aws_byte_buf *out); -}; - -struct aws_hmac { - struct aws_allocator *allocator; - struct aws_hmac_vtable *vtable; - size_t digest_size; - bool good; - void *impl; -}; - -typedef struct aws_hmac *(aws_hmac_new_fn)(struct aws_allocator *allocator, const struct aws_byte_cursor *secret); - -AWS_EXTERN_C_BEGIN -/** - * Allocates and initializes a sha256 hmac instance. Secret is the key to be - * used for the hmac process. - */ -AWS_CAL_API struct aws_hmac *aws_sha256_hmac_new(struct aws_allocator *allocator, const struct aws_byte_cursor *secret); - -/** - * Cleans up and deallocates hmac. - */ -AWS_CAL_API void aws_hmac_destroy(struct aws_hmac *hmac); - -/** - * Updates the running hmac with to_hash. this can be called multiple times. - */ -AWS_CAL_API int aws_hmac_update(struct aws_hmac *hmac, const struct aws_byte_cursor *to_hmac); -/** - * Completes the hmac computation and writes the final digest to output. - * Allocation of output is the caller's responsibility. If you specify - * truncate_to to something other than 0, the output will be truncated to that - * number of bytes. For example if you want a SHA256 digest as the first 16 - * bytes, set truncate_to to 16. If you want the full digest size, just set this - * to 0. - */ -AWS_CAL_API int aws_hmac_finalize(struct aws_hmac *hmac, struct aws_byte_buf *output, size_t truncate_to); -/** - * Computes the sha256 hmac over input and writes the digest output to 'output'. - * Use this if you don't need to stream the data you're hashing and you can load - * the entire input to hash into memory. If you specify truncate_to to something - * other than 0, the output will be truncated to that number of bytes. For - * example if you want a SHA256 HMAC digest as the first 16 bytes, set - * truncate_to to 16. If you want the full digest size, just set this to 0. - */ -AWS_CAL_API int aws_sha256_hmac_compute( - struct aws_allocator *allocator, - const struct aws_byte_cursor *secret, - const struct aws_byte_cursor *to_hmac, - struct aws_byte_buf *output, - size_t truncate_to); -/** - * Set the implementation of sha256 hmac to use. If you compiled without - * AWS_BYO_CRYPTO, you do not need to call this. However, if use this, we will - * honor it, regardless of compile options. This may be useful for testing - * purposes. If you did set AWS_BYO_CRYPTO, and you do not call this function - * you will segfault. - */ -AWS_CAL_API void aws_set_sha256_hmac_new_fn(aws_hmac_new_fn *fn); - -AWS_EXTERN_C_END - -#endif /* AWS_CAL_HASH_H_ */ +#ifndef AWS_CAL_HMAC_H_ +#define AWS_CAL_HMAC_H_ +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ +#include <aws/cal/exports.h> + +#include <aws/common/byte_buf.h> +#include <aws/common/common.h> + +#define AWS_SHA256_HMAC_LEN 32 + +struct aws_hmac; + +struct aws_hmac_vtable { + const char *alg_name; + const char *provider; + void (*destroy)(struct aws_hmac *hmac); + int (*update)(struct aws_hmac *hmac, const struct aws_byte_cursor *buf); + int (*finalize)(struct aws_hmac *hmac, struct aws_byte_buf *out); +}; + +struct aws_hmac { + struct aws_allocator *allocator; + struct aws_hmac_vtable *vtable; + size_t digest_size; + bool good; + void *impl; +}; + +typedef struct aws_hmac *(aws_hmac_new_fn)(struct aws_allocator *allocator, const struct aws_byte_cursor *secret); + +AWS_EXTERN_C_BEGIN +/** + * Allocates and initializes a sha256 hmac instance. Secret is the key to be + * used for the hmac process. + */ +AWS_CAL_API struct aws_hmac *aws_sha256_hmac_new(struct aws_allocator *allocator, const struct aws_byte_cursor *secret); + +/** + * Cleans up and deallocates hmac. + */ +AWS_CAL_API void aws_hmac_destroy(struct aws_hmac *hmac); + +/** + * Updates the running hmac with to_hash. this can be called multiple times. + */ +AWS_CAL_API int aws_hmac_update(struct aws_hmac *hmac, const struct aws_byte_cursor *to_hmac); +/** + * Completes the hmac computation and writes the final digest to output. + * Allocation of output is the caller's responsibility. If you specify + * truncate_to to something other than 0, the output will be truncated to that + * number of bytes. For example if you want a SHA256 digest as the first 16 + * bytes, set truncate_to to 16. If you want the full digest size, just set this + * to 0. + */ +AWS_CAL_API int aws_hmac_finalize(struct aws_hmac *hmac, struct aws_byte_buf *output, size_t truncate_to); +/** + * Computes the sha256 hmac over input and writes the digest output to 'output'. + * Use this if you don't need to stream the data you're hashing and you can load + * the entire input to hash into memory. If you specify truncate_to to something + * other than 0, the output will be truncated to that number of bytes. For + * example if you want a SHA256 HMAC digest as the first 16 bytes, set + * truncate_to to 16. If you want the full digest size, just set this to 0. + */ +AWS_CAL_API int aws_sha256_hmac_compute( + struct aws_allocator *allocator, + const struct aws_byte_cursor *secret, + const struct aws_byte_cursor *to_hmac, + struct aws_byte_buf *output, + size_t truncate_to); +/** + * Set the implementation of sha256 hmac to use. If you compiled without + * AWS_BYO_CRYPTO, you do not need to call this. However, if use this, we will + * honor it, regardless of compile options. This may be useful for testing + * purposes. If you did set AWS_BYO_CRYPTO, and you do not call this function + * you will segfault. + */ +AWS_CAL_API void aws_set_sha256_hmac_new_fn(aws_hmac_new_fn *fn); + +AWS_EXTERN_C_END + +#endif /* AWS_CAL_HASH_H_ */ diff --git a/contrib/restricted/aws/aws-c-cal/include/aws/cal/private/der.h b/contrib/restricted/aws/aws-c-cal/include/aws/cal/private/der.h index e263864a49..3486e3f476 100644 --- a/contrib/restricted/aws/aws-c-cal/include/aws/cal/private/der.h +++ b/contrib/restricted/aws/aws-c-cal/include/aws/cal/private/der.h @@ -1,218 +1,218 @@ -#ifndef AWS_C_CAL_DER_H -#define AWS_C_CAL_DER_H -/** - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0. - */ - -#include <aws/cal/exports.h> - -#include <aws/common/array_list.h> -#include <aws/common/byte_buf.h> - -struct aws_der_encoder; -struct aws_der_decoder; - -enum aws_der_type { - /* Primitives */ - AWS_DER_BOOLEAN = 0x01, - AWS_DER_INTEGER = 0x02, - AWS_DER_BIT_STRING = 0x03, - AWS_DER_OCTET_STRING = 0x04, - AWS_DER_NULL = 0x05, - AWS_DER_OBJECT_IDENTIFIER = 0x06, - AWS_DER_BMPString = 0x1e, - AWS_DER_UNICODE_STRING = AWS_DER_BMPString, - AWS_DER_IA5String = 0x16, /* Unsupported */ - AWS_DER_PrintableString = 0x13, - AWS_DER_TeletexString = 0x14, /* Unsupported */ - - /* Constructed types */ - AWS_DER_SEQUENCE = 0x30, - AWS_DER_SEQUENCE_OF = AWS_DER_SEQUENCE, - AWS_DER_SET = 0x31, - AWS_DER_SET_OF = AWS_DER_SET, - AWS_DER_UTF8_STRING = 0x0c, - - /* class types */ - AWS_DER_CLASS_UNIVERSAL = 0x00, - AWS_DER_CLASS_APPLICATION = 0x40, - AWS_DER_CLASS_CONTEXT = 0x80, - AWS_DER_CLASS_PRIVATE = 0xc0, - - /* forms */ - AWS_DER_FORM_CONSTRUCTED = 0x20, - AWS_DER_FORM_PRIMITIVE = 0x00, -}; - -AWS_EXTERN_C_BEGIN - -/** - * Initializes a DER encoder - * @param allocator The allocator to use for all allocations within the encoder - * @param capacity The initial capacity of the encoder scratch buffer (the max size of all encoded TLVs) - * @return AWS_OP_ERR if an error occurs, otherwise AWS_OP_SUCCESS - */ -AWS_CAL_API struct aws_der_encoder *aws_der_encoder_new(struct aws_allocator *allocator, size_t capacity); - -/** - * Cleans up a DER encoder - * @param encoder The encoder to clean up - * - * Note that this destroys the encoder buffer, invalidating any references to the contents given via get_contents() - */ -AWS_CAL_API void aws_der_encoder_destroy(struct aws_der_encoder *encoder); - -/** - * Writes an arbitrarily sized integer to the DER stream - * @param encoder The encoder to use - * @param integer A cursor pointing to the integer's memory - * @return AWS_OP_ERR if an error occurs, otherwise AWS_OP_SUCCESS - */ -AWS_CAL_API int aws_der_encoder_write_integer(struct aws_der_encoder *encoder, struct aws_byte_cursor integer); -/** - * Writes a boolean to the DER stream - * @param encoder The encoder to use - * @param boolean The boolean to write - * @return AWS_OP_ERR if an error occurs, otherwise AWS_OP_SUCCESS - */ -AWS_CAL_API int aws_der_encoder_write_boolean(struct aws_der_encoder *encoder, bool boolean); - -/** - * Writes a NULL token to the stream - * @param encoder The encoder to write to - * @return AWS_OP_ERR if an error occurs, otherwise AWS_OP_SUCCESS - */ -AWS_CAL_API int aws_der_encoder_write_null(struct aws_der_encoder *encoder); - -/** - * Writes a BIT_STRING to the stream - * @param encoder The encoder to use - * @param bit_string The bit string to encode - * @return AWS_OP_ERR if an error occurs, otherwise AWS_OP_SUCCESS - */ -AWS_CAL_API int aws_der_encoder_write_bit_string(struct aws_der_encoder *encoder, struct aws_byte_cursor bit_string); - -/** - * Writes a string to the stream - * @param encoder The encoder to use - * @param octet_string The string to encode - * @return AWS_OP_ERR if an error occurs, otherwise AWS_OP_SUCCESS - */ -AWS_CAL_API int aws_der_encoder_write_octet_string( - struct aws_der_encoder *encoder, - struct aws_byte_cursor octet_string); - -/** - * Begins a SEQUENCE of objects in the DER stream - * @param encoder The encoder to use - * @return AWS_OP_ERR if an error occurs, otherwise AWS_OP_SUCCESS - */ -AWS_CAL_API int aws_der_encoder_begin_sequence(struct aws_der_encoder *encoder); - -/** - * Finishes a SEQUENCE and applies it to the DER stream buffer - * @param encoder The encoder to update - * @return AWS_OP_ERR if an error occurs, otherwise AWS_OP_SUCCESS - */ -AWS_CAL_API int aws_der_encoder_end_sequence(struct aws_der_encoder *encoder); - -/** - * Begins a SET of objects in the DER stream - * @param encoder The encoder to use - * @return AWS_OP_ERR if an error occurs, otherwise AWS_OP_SUCCESS - */ -AWS_CAL_API int aws_der_encoder_begin_set(struct aws_der_encoder *encoder); - -/** - * Finishes a SET and applies it to the DER stream buffer - * @param encoder The encoder to update - * @return AWS_OP_ERR if an error occurs, otherwise AWS_OP_SUCCESS - */ -AWS_CAL_API int aws_der_encoder_end_set(struct aws_der_encoder *encoder); - -/** - * Retrieves the contents of the encoder stream buffer - * @param encoder The encoder to read from - * @param cursor The cursor to point at the stream buffer - * @return AWS_OP_ERR if an error occurs, otherwise AWS_OP_SUCCESS - */ -AWS_CAL_API int aws_der_encoder_get_contents(struct aws_der_encoder *encoder, struct aws_byte_cursor *contents); - -/** - * Initializes an DER decoder - * @param allocator The allocator to use - * @param input The DER formatted buffer to parse - * @return Initialized decoder, or NULL - */ -AWS_CAL_API struct aws_der_decoder *aws_der_decoder_new(struct aws_allocator *allocator, struct aws_byte_cursor input); - -/** - * Cleans up a DER encoder - * @param decoder The encoder to clean up - */ -AWS_CAL_API void aws_der_decoder_destroy(struct aws_der_decoder *decoder); - -/** - * Allows for iteration over the decoded TLVs. - * @param decoder The decoder to iterate over - * @return true if there is a tlv to read after advancing, false when done - */ -AWS_CAL_API bool aws_der_decoder_next(struct aws_der_decoder *decoder); - -/** - * The type of the current TLV - * @param decoder The decoder to inspect - * @return AWS_OP_ERR if an error occurs, otherwise AWS_OP_SUCCESS - */ -AWS_CAL_API enum aws_der_type aws_der_decoder_tlv_type(struct aws_der_decoder *decoder); - -/** - * The size of the current TLV - * @param decoder The decoder to inspect - * @return AWS_OP_ERR if an error occurs, otherwise AWS_OP_SUCCESS - */ -AWS_CAL_API size_t aws_der_decoder_tlv_length(struct aws_der_decoder *decoder); - -/** - * The number of elements in the current TLV container - * @param decoder The decoder to inspect - * @return Number of elements in the current container - */ -AWS_CAL_API size_t aws_der_decoder_tlv_count(struct aws_der_decoder *decoder); - -/** - * Extracts the current TLV string value (BIT_STRING, OCTET_STRING) - * @param decoder The decoder to extract from - * @param string The buffer to store the string into - * @return AWS_OP_ERR if an error occurs, otherwise AWS_OP_SUCCESS - */ -AWS_CAL_API int aws_der_decoder_tlv_string(struct aws_der_decoder *decoder, struct aws_byte_cursor *string); - -/** - * Extracts the current TLV INTEGER value (INTEGER) - * @param decoder The decoder to extract from - * @param integer The buffer to store the integer into - * @return AWS_OP_ERR if an error occurs, otherwise AWS_OP_SUCCESS - */ -AWS_CAL_API int aws_der_decoder_tlv_integer(struct aws_der_decoder *decoder, struct aws_byte_cursor *integer); - -/** - * Extracts the current TLV BOOLEAN value (BOOLEAN) - * @param decoder The decoder to extract from - * @param boolean The boolean to store the value into - * @return AWS_OP_ERR if an error occurs, otherwise AWS_OP_SUCCESS - */ -AWS_CAL_API int aws_der_decoder_tlv_boolean(struct aws_der_decoder *decoder, bool *boolean); - -/** - * Extracts the current TLV value as a blob - * @param decoder The decoder to extract from - * @param blob The buffer to store the value into - * @return AWS_OP_ERR if an error occurs, otherwise AWS_OP_SUCCESS - */ -AWS_CAL_API int aws_der_decoder_tlv_blob(struct aws_der_decoder *decoder, struct aws_byte_cursor *blob); - -AWS_EXTERN_C_END - -#endif +#ifndef AWS_C_CAL_DER_H +#define AWS_C_CAL_DER_H +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#include <aws/cal/exports.h> + +#include <aws/common/array_list.h> +#include <aws/common/byte_buf.h> + +struct aws_der_encoder; +struct aws_der_decoder; + +enum aws_der_type { + /* Primitives */ + AWS_DER_BOOLEAN = 0x01, + AWS_DER_INTEGER = 0x02, + AWS_DER_BIT_STRING = 0x03, + AWS_DER_OCTET_STRING = 0x04, + AWS_DER_NULL = 0x05, + AWS_DER_OBJECT_IDENTIFIER = 0x06, + AWS_DER_BMPString = 0x1e, + AWS_DER_UNICODE_STRING = AWS_DER_BMPString, + AWS_DER_IA5String = 0x16, /* Unsupported */ + AWS_DER_PrintableString = 0x13, + AWS_DER_TeletexString = 0x14, /* Unsupported */ + + /* Constructed types */ + AWS_DER_SEQUENCE = 0x30, + AWS_DER_SEQUENCE_OF = AWS_DER_SEQUENCE, + AWS_DER_SET = 0x31, + AWS_DER_SET_OF = AWS_DER_SET, + AWS_DER_UTF8_STRING = 0x0c, + + /* class types */ + AWS_DER_CLASS_UNIVERSAL = 0x00, + AWS_DER_CLASS_APPLICATION = 0x40, + AWS_DER_CLASS_CONTEXT = 0x80, + AWS_DER_CLASS_PRIVATE = 0xc0, + + /* forms */ + AWS_DER_FORM_CONSTRUCTED = 0x20, + AWS_DER_FORM_PRIMITIVE = 0x00, +}; + +AWS_EXTERN_C_BEGIN + +/** + * Initializes a DER encoder + * @param allocator The allocator to use for all allocations within the encoder + * @param capacity The initial capacity of the encoder scratch buffer (the max size of all encoded TLVs) + * @return AWS_OP_ERR if an error occurs, otherwise AWS_OP_SUCCESS + */ +AWS_CAL_API struct aws_der_encoder *aws_der_encoder_new(struct aws_allocator *allocator, size_t capacity); + +/** + * Cleans up a DER encoder + * @param encoder The encoder to clean up + * + * Note that this destroys the encoder buffer, invalidating any references to the contents given via get_contents() + */ +AWS_CAL_API void aws_der_encoder_destroy(struct aws_der_encoder *encoder); + +/** + * Writes an arbitrarily sized integer to the DER stream + * @param encoder The encoder to use + * @param integer A cursor pointing to the integer's memory + * @return AWS_OP_ERR if an error occurs, otherwise AWS_OP_SUCCESS + */ +AWS_CAL_API int aws_der_encoder_write_integer(struct aws_der_encoder *encoder, struct aws_byte_cursor integer); +/** + * Writes a boolean to the DER stream + * @param encoder The encoder to use + * @param boolean The boolean to write + * @return AWS_OP_ERR if an error occurs, otherwise AWS_OP_SUCCESS + */ +AWS_CAL_API int aws_der_encoder_write_boolean(struct aws_der_encoder *encoder, bool boolean); + +/** + * Writes a NULL token to the stream + * @param encoder The encoder to write to + * @return AWS_OP_ERR if an error occurs, otherwise AWS_OP_SUCCESS + */ +AWS_CAL_API int aws_der_encoder_write_null(struct aws_der_encoder *encoder); + +/** + * Writes a BIT_STRING to the stream + * @param encoder The encoder to use + * @param bit_string The bit string to encode + * @return AWS_OP_ERR if an error occurs, otherwise AWS_OP_SUCCESS + */ +AWS_CAL_API int aws_der_encoder_write_bit_string(struct aws_der_encoder *encoder, struct aws_byte_cursor bit_string); + +/** + * Writes a string to the stream + * @param encoder The encoder to use + * @param octet_string The string to encode + * @return AWS_OP_ERR if an error occurs, otherwise AWS_OP_SUCCESS + */ +AWS_CAL_API int aws_der_encoder_write_octet_string( + struct aws_der_encoder *encoder, + struct aws_byte_cursor octet_string); + +/** + * Begins a SEQUENCE of objects in the DER stream + * @param encoder The encoder to use + * @return AWS_OP_ERR if an error occurs, otherwise AWS_OP_SUCCESS + */ +AWS_CAL_API int aws_der_encoder_begin_sequence(struct aws_der_encoder *encoder); + +/** + * Finishes a SEQUENCE and applies it to the DER stream buffer + * @param encoder The encoder to update + * @return AWS_OP_ERR if an error occurs, otherwise AWS_OP_SUCCESS + */ +AWS_CAL_API int aws_der_encoder_end_sequence(struct aws_der_encoder *encoder); + +/** + * Begins a SET of objects in the DER stream + * @param encoder The encoder to use + * @return AWS_OP_ERR if an error occurs, otherwise AWS_OP_SUCCESS + */ +AWS_CAL_API int aws_der_encoder_begin_set(struct aws_der_encoder *encoder); + +/** + * Finishes a SET and applies it to the DER stream buffer + * @param encoder The encoder to update + * @return AWS_OP_ERR if an error occurs, otherwise AWS_OP_SUCCESS + */ +AWS_CAL_API int aws_der_encoder_end_set(struct aws_der_encoder *encoder); + +/** + * Retrieves the contents of the encoder stream buffer + * @param encoder The encoder to read from + * @param cursor The cursor to point at the stream buffer + * @return AWS_OP_ERR if an error occurs, otherwise AWS_OP_SUCCESS + */ +AWS_CAL_API int aws_der_encoder_get_contents(struct aws_der_encoder *encoder, struct aws_byte_cursor *contents); + +/** + * Initializes an DER decoder + * @param allocator The allocator to use + * @param input The DER formatted buffer to parse + * @return Initialized decoder, or NULL + */ +AWS_CAL_API struct aws_der_decoder *aws_der_decoder_new(struct aws_allocator *allocator, struct aws_byte_cursor input); + +/** + * Cleans up a DER encoder + * @param decoder The encoder to clean up + */ +AWS_CAL_API void aws_der_decoder_destroy(struct aws_der_decoder *decoder); + +/** + * Allows for iteration over the decoded TLVs. + * @param decoder The decoder to iterate over + * @return true if there is a tlv to read after advancing, false when done + */ +AWS_CAL_API bool aws_der_decoder_next(struct aws_der_decoder *decoder); + +/** + * The type of the current TLV + * @param decoder The decoder to inspect + * @return AWS_OP_ERR if an error occurs, otherwise AWS_OP_SUCCESS + */ +AWS_CAL_API enum aws_der_type aws_der_decoder_tlv_type(struct aws_der_decoder *decoder); + +/** + * The size of the current TLV + * @param decoder The decoder to inspect + * @return AWS_OP_ERR if an error occurs, otherwise AWS_OP_SUCCESS + */ +AWS_CAL_API size_t aws_der_decoder_tlv_length(struct aws_der_decoder *decoder); + +/** + * The number of elements in the current TLV container + * @param decoder The decoder to inspect + * @return Number of elements in the current container + */ +AWS_CAL_API size_t aws_der_decoder_tlv_count(struct aws_der_decoder *decoder); + +/** + * Extracts the current TLV string value (BIT_STRING, OCTET_STRING) + * @param decoder The decoder to extract from + * @param string The buffer to store the string into + * @return AWS_OP_ERR if an error occurs, otherwise AWS_OP_SUCCESS + */ +AWS_CAL_API int aws_der_decoder_tlv_string(struct aws_der_decoder *decoder, struct aws_byte_cursor *string); + +/** + * Extracts the current TLV INTEGER value (INTEGER) + * @param decoder The decoder to extract from + * @param integer The buffer to store the integer into + * @return AWS_OP_ERR if an error occurs, otherwise AWS_OP_SUCCESS + */ +AWS_CAL_API int aws_der_decoder_tlv_integer(struct aws_der_decoder *decoder, struct aws_byte_cursor *integer); + +/** + * Extracts the current TLV BOOLEAN value (BOOLEAN) + * @param decoder The decoder to extract from + * @param boolean The boolean to store the value into + * @return AWS_OP_ERR if an error occurs, otherwise AWS_OP_SUCCESS + */ +AWS_CAL_API int aws_der_decoder_tlv_boolean(struct aws_der_decoder *decoder, bool *boolean); + +/** + * Extracts the current TLV value as a blob + * @param decoder The decoder to extract from + * @param blob The buffer to store the value into + * @return AWS_OP_ERR if an error occurs, otherwise AWS_OP_SUCCESS + */ +AWS_CAL_API int aws_der_decoder_tlv_blob(struct aws_der_decoder *decoder, struct aws_byte_cursor *blob); + +AWS_EXTERN_C_END + +#endif diff --git a/contrib/restricted/aws/aws-c-cal/include/aws/cal/private/ecc.h b/contrib/restricted/aws/aws-c-cal/include/aws/cal/private/ecc.h index bbed69b547..ec3492518c 100644 --- a/contrib/restricted/aws/aws-c-cal/include/aws/cal/private/ecc.h +++ b/contrib/restricted/aws/aws-c-cal/include/aws/cal/private/ecc.h @@ -1,25 +1,25 @@ -#ifndef AWS_C_CAL_PRIVATE_ECC_H -#define AWS_C_CAL_PRIVATE_ECC_H -/** - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0. - */ - -#include <aws/cal/ecc.h> - -#include <aws/common/byte_buf.h> - -struct aws_der_decoder; - -AWS_EXTERN_C_BEGIN - -AWS_CAL_API int aws_der_decoder_load_ecc_key_pair( - struct aws_der_decoder *decoder, - struct aws_byte_cursor *out_public_x_coor, - struct aws_byte_cursor *out_public_y_coor, - struct aws_byte_cursor *out_private_d, - enum aws_ecc_curve_name *out_curve_name); - -AWS_EXTERN_C_END - -#endif /* AWS_C_CAL_PRIVATE_ECC_H */ +#ifndef AWS_C_CAL_PRIVATE_ECC_H +#define AWS_C_CAL_PRIVATE_ECC_H +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#include <aws/cal/ecc.h> + +#include <aws/common/byte_buf.h> + +struct aws_der_decoder; + +AWS_EXTERN_C_BEGIN + +AWS_CAL_API int aws_der_decoder_load_ecc_key_pair( + struct aws_der_decoder *decoder, + struct aws_byte_cursor *out_public_x_coor, + struct aws_byte_cursor *out_public_y_coor, + struct aws_byte_cursor *out_private_d, + enum aws_ecc_curve_name *out_curve_name); + +AWS_EXTERN_C_END + +#endif /* AWS_C_CAL_PRIVATE_ECC_H */ diff --git a/contrib/restricted/aws/aws-c-cal/include/aws/cal/private/opensslcrypto_common.h b/contrib/restricted/aws/aws-c-cal/include/aws/cal/private/opensslcrypto_common.h index 6628db1e5c..f4e25c5f35 100644 --- a/contrib/restricted/aws/aws-c-cal/include/aws/cal/private/opensslcrypto_common.h +++ b/contrib/restricted/aws/aws-c-cal/include/aws/cal/private/opensslcrypto_common.h @@ -1,46 +1,46 @@ -#ifndef AWS_C_CAL_OPENSSLCRYPTO_COMMON_H -#define AWS_C_CAL_OPENSSLCRYPTO_COMMON_H - -#include <openssl/crypto.h> -#include <openssl/evp.h> -#include <openssl/hmac.h> - -typedef HMAC_CTX *(*hmac_ctx_new)(void); -typedef int (*hmac_ctx_reset)(HMAC_CTX *); -typedef void (*hmac_ctx_free)(HMAC_CTX *); -typedef void (*hmac_ctx_init)(HMAC_CTX *); -typedef int (*hmac_ctx_init_ex)(HMAC_CTX *, const void *, int, const EVP_MD *, ENGINE *); -typedef void (*hmac_ctx_clean_up)(HMAC_CTX *); -typedef int (*hmac_ctx_update)(HMAC_CTX *, const unsigned char *, size_t); -typedef int (*hmac_ctx_final)(HMAC_CTX *, unsigned char *, unsigned int *); - -struct openssl_hmac_ctx_table { - hmac_ctx_new new_fn; - hmac_ctx_free free_fn; - hmac_ctx_init init_fn; - hmac_ctx_init_ex init_ex_fn; - hmac_ctx_clean_up clean_up_fn; - hmac_ctx_update update_fn; - hmac_ctx_final final_fn; - hmac_ctx_reset reset_fn; -}; - -extern struct openssl_hmac_ctx_table *g_aws_openssl_hmac_ctx_table; - -typedef EVP_MD_CTX *(*evp_md_ctx_new)(void); -typedef void (*evp_md_ctx_free)(EVP_MD_CTX *); -typedef int (*evp_md_ctx_digest_init_ex)(EVP_MD_CTX *, const EVP_MD *, ENGINE *); -typedef int (*evp_md_ctx_digest_update)(EVP_MD_CTX *, const void *, size_t); -typedef int (*evp_md_ctx_digest_final_ex)(EVP_MD_CTX *, unsigned char *, unsigned int *); - -struct openssl_evp_md_ctx_table { - evp_md_ctx_new new_fn; - evp_md_ctx_free free_fn; - evp_md_ctx_digest_init_ex init_ex_fn; - evp_md_ctx_digest_update update_fn; - evp_md_ctx_digest_final_ex final_ex_fn; -}; - -extern struct openssl_evp_md_ctx_table *g_aws_openssl_evp_md_ctx_table; - -#endif /* AWS_C_CAL_OPENSSLCRYPTO_COMMON_H */ +#ifndef AWS_C_CAL_OPENSSLCRYPTO_COMMON_H +#define AWS_C_CAL_OPENSSLCRYPTO_COMMON_H + +#include <openssl/crypto.h> +#include <openssl/evp.h> +#include <openssl/hmac.h> + +typedef HMAC_CTX *(*hmac_ctx_new)(void); +typedef int (*hmac_ctx_reset)(HMAC_CTX *); +typedef void (*hmac_ctx_free)(HMAC_CTX *); +typedef void (*hmac_ctx_init)(HMAC_CTX *); +typedef int (*hmac_ctx_init_ex)(HMAC_CTX *, const void *, int, const EVP_MD *, ENGINE *); +typedef void (*hmac_ctx_clean_up)(HMAC_CTX *); +typedef int (*hmac_ctx_update)(HMAC_CTX *, const unsigned char *, size_t); +typedef int (*hmac_ctx_final)(HMAC_CTX *, unsigned char *, unsigned int *); + +struct openssl_hmac_ctx_table { + hmac_ctx_new new_fn; + hmac_ctx_free free_fn; + hmac_ctx_init init_fn; + hmac_ctx_init_ex init_ex_fn; + hmac_ctx_clean_up clean_up_fn; + hmac_ctx_update update_fn; + hmac_ctx_final final_fn; + hmac_ctx_reset reset_fn; +}; + +extern struct openssl_hmac_ctx_table *g_aws_openssl_hmac_ctx_table; + +typedef EVP_MD_CTX *(*evp_md_ctx_new)(void); +typedef void (*evp_md_ctx_free)(EVP_MD_CTX *); +typedef int (*evp_md_ctx_digest_init_ex)(EVP_MD_CTX *, const EVP_MD *, ENGINE *); +typedef int (*evp_md_ctx_digest_update)(EVP_MD_CTX *, const void *, size_t); +typedef int (*evp_md_ctx_digest_final_ex)(EVP_MD_CTX *, unsigned char *, unsigned int *); + +struct openssl_evp_md_ctx_table { + evp_md_ctx_new new_fn; + evp_md_ctx_free free_fn; + evp_md_ctx_digest_init_ex init_ex_fn; + evp_md_ctx_digest_update update_fn; + evp_md_ctx_digest_final_ex final_ex_fn; +}; + +extern struct openssl_evp_md_ctx_table *g_aws_openssl_evp_md_ctx_table; + +#endif /* AWS_C_CAL_OPENSSLCRYPTO_COMMON_H */ diff --git a/contrib/restricted/aws/aws-c-cal/source/cal.c b/contrib/restricted/aws/aws-c-cal/source/cal.c index 100e7fd034..d0792ce09a 100644 --- a/contrib/restricted/aws/aws-c-cal/source/cal.c +++ b/contrib/restricted/aws/aws-c-cal/source/cal.c @@ -1,63 +1,63 @@ -/** - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0. - */ -#include <aws/cal/cal.h> -#include <aws/common/common.h> -#include <aws/common/error.h> - -#define AWS_DEFINE_ERROR_INFO_CAL(CODE, STR) [(CODE)-0x1C00] = AWS_DEFINE_ERROR_INFO(CODE, STR, "aws-c-cal") - -static struct aws_error_info s_errors[] = { - AWS_DEFINE_ERROR_INFO_CAL(AWS_ERROR_CAL_SIGNATURE_VALIDATION_FAILED, "Verify on a cryptographic signature failed."), - AWS_DEFINE_ERROR_INFO_CAL( - AWS_ERROR_CAL_MISSING_REQUIRED_KEY_COMPONENT, - "An attempt was made to perform an " - "Asymmetric cryptographic operation with the" - "wrong key component. For example, attempt to" - "verify a signature with a private key or " - "sign a message with a public key."), - AWS_DEFINE_ERROR_INFO_CAL( - AWS_ERROR_CAL_INVALID_KEY_LENGTH_FOR_ALGORITHM, - "A key length was used for an algorithm that needs a different key length"), - AWS_DEFINE_ERROR_INFO_CAL( - AWS_ERROR_CAL_UNKNOWN_OBJECT_IDENTIFIER, - "An ASN.1 OID was encountered that wasn't expected or understood. Most likely, an unsupported algorithm was " - "encountered."), - AWS_DEFINE_ERROR_INFO_CAL( - AWS_ERROR_CAL_MALFORMED_ASN1_ENCOUNTERED, - "An ASN.1 DER decoding operation failed on malformed input."), - AWS_DEFINE_ERROR_INFO_CAL( - AWS_ERROR_CAL_MISMATCHED_DER_TYPE, - "An invalid DER type was requested during encoding/decoding"), - AWS_DEFINE_ERROR_INFO_CAL( - AWS_ERROR_CAL_UNSUPPORTED_ALGORITHM, - "The specified algorithim is unsupported on this platform."), -}; - -static struct aws_error_info_list s_list = { - .error_list = s_errors, - .count = AWS_ARRAY_SIZE(s_errors), -}; - -extern void aws_cal_platform_init(struct aws_allocator *allocator); -extern void aws_cal_platform_clean_up(void); - -static bool s_cal_library_initialized = false; - -void aws_cal_library_init(struct aws_allocator *allocator) { - if (!s_cal_library_initialized) { - aws_common_library_init(allocator); - aws_register_error_info(&s_list); - aws_cal_platform_init(allocator); - s_cal_library_initialized = true; - } -} -void aws_cal_library_clean_up(void) { - if (s_cal_library_initialized) { - s_cal_library_initialized = false; - aws_cal_platform_clean_up(); - aws_unregister_error_info(&s_list); - aws_common_library_clean_up(); - } -} +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ +#include <aws/cal/cal.h> +#include <aws/common/common.h> +#include <aws/common/error.h> + +#define AWS_DEFINE_ERROR_INFO_CAL(CODE, STR) [(CODE)-0x1C00] = AWS_DEFINE_ERROR_INFO(CODE, STR, "aws-c-cal") + +static struct aws_error_info s_errors[] = { + AWS_DEFINE_ERROR_INFO_CAL(AWS_ERROR_CAL_SIGNATURE_VALIDATION_FAILED, "Verify on a cryptographic signature failed."), + AWS_DEFINE_ERROR_INFO_CAL( + AWS_ERROR_CAL_MISSING_REQUIRED_KEY_COMPONENT, + "An attempt was made to perform an " + "Asymmetric cryptographic operation with the" + "wrong key component. For example, attempt to" + "verify a signature with a private key or " + "sign a message with a public key."), + AWS_DEFINE_ERROR_INFO_CAL( + AWS_ERROR_CAL_INVALID_KEY_LENGTH_FOR_ALGORITHM, + "A key length was used for an algorithm that needs a different key length"), + AWS_DEFINE_ERROR_INFO_CAL( + AWS_ERROR_CAL_UNKNOWN_OBJECT_IDENTIFIER, + "An ASN.1 OID was encountered that wasn't expected or understood. Most likely, an unsupported algorithm was " + "encountered."), + AWS_DEFINE_ERROR_INFO_CAL( + AWS_ERROR_CAL_MALFORMED_ASN1_ENCOUNTERED, + "An ASN.1 DER decoding operation failed on malformed input."), + AWS_DEFINE_ERROR_INFO_CAL( + AWS_ERROR_CAL_MISMATCHED_DER_TYPE, + "An invalid DER type was requested during encoding/decoding"), + AWS_DEFINE_ERROR_INFO_CAL( + AWS_ERROR_CAL_UNSUPPORTED_ALGORITHM, + "The specified algorithim is unsupported on this platform."), +}; + +static struct aws_error_info_list s_list = { + .error_list = s_errors, + .count = AWS_ARRAY_SIZE(s_errors), +}; + +extern void aws_cal_platform_init(struct aws_allocator *allocator); +extern void aws_cal_platform_clean_up(void); + +static bool s_cal_library_initialized = false; + +void aws_cal_library_init(struct aws_allocator *allocator) { + if (!s_cal_library_initialized) { + aws_common_library_init(allocator); + aws_register_error_info(&s_list); + aws_cal_platform_init(allocator); + s_cal_library_initialized = true; + } +} +void aws_cal_library_clean_up(void) { + if (s_cal_library_initialized) { + s_cal_library_initialized = false; + aws_cal_platform_clean_up(); + aws_unregister_error_info(&s_list); + aws_common_library_clean_up(); + } +} diff --git a/contrib/restricted/aws/aws-c-cal/source/der.c b/contrib/restricted/aws/aws-c-cal/source/der.c index 0209eeb170..546a5685b5 100644 --- a/contrib/restricted/aws/aws-c-cal/source/der.c +++ b/contrib/restricted/aws/aws-c-cal/source/der.c @@ -1,501 +1,501 @@ -/** - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0. - */ - -#include <aws/cal/private/der.h> - -#include <aws/cal/cal.h> -#include <aws/common/byte_buf.h> - -#ifdef _MSC_VER -# pragma warning(push) -# pragma warning(disable : 4204 4221) /* non-standard aggregate initializer warnings */ -#endif - -struct aws_der_encoder { - struct aws_allocator *allocator; - struct aws_byte_buf storage; - struct aws_byte_buf *buffer; /* buffer being written to, might be storage, might be a sequence/set buffer */ - struct aws_array_list stack; -}; - -struct aws_der_decoder { - struct aws_allocator *allocator; - struct aws_array_list tlvs; /* parsed elements */ - int tlv_idx; /* index to elements after parsing */ - struct aws_byte_cursor input; /* input buffer */ - uint32_t depth; /* recursion depth when expanding containers */ - struct der_tlv *container; /* currently expanding container */ -}; - -struct der_tlv { - uint8_t tag; - uint32_t length; /* length of value in bytes */ - uint32_t count; /* SEQUENCE or SET element count */ - uint8_t *value; -}; - -static void s_decode_tlv(struct der_tlv *tlv) { - if (tlv->tag == AWS_DER_INTEGER) { - uint8_t first_byte = tlv->value[0]; - /* if the first byte is 0, it just denotes unsigned and should be removed */ - if (first_byte == 0x00) { - tlv->length -= 1; - tlv->value += 1; - } - } else if (tlv->tag == AWS_DER_BIT_STRING) { - /* skip over the trailing skipped bit count */ - tlv->length -= 1; - tlv->value += 1; - } -} - -static int s_der_read_tlv(struct aws_byte_cursor *cur, struct der_tlv *tlv) { - uint8_t tag = 0; - uint8_t len_bytes = 0; - uint32_t len = 0; - if (!aws_byte_cursor_read_u8(cur, &tag)) { - return AWS_OP_ERR; - } - if (!aws_byte_cursor_read_u8(cur, &len_bytes)) { - return AWS_OP_ERR; - } - /* if the sign bit is set, then the first byte is the number of bytes required to store - * the length */ - if (len_bytes & 0x80) { - len_bytes &= 0x7f; - switch (len_bytes) { - case 1: - if (!aws_byte_cursor_read_u8(cur, (uint8_t *)&len)) { - return aws_raise_error(AWS_ERROR_CAL_MALFORMED_ASN1_ENCOUNTERED); - } - break; - case 2: - if (!aws_byte_cursor_read_be16(cur, (uint16_t *)&len)) { - return aws_raise_error(AWS_ERROR_CAL_MALFORMED_ASN1_ENCOUNTERED); - } - break; - case 4: - if (!aws_byte_cursor_read_be32(cur, &len)) { - return aws_raise_error(AWS_ERROR_CAL_MALFORMED_ASN1_ENCOUNTERED); - } - break; - default: - return aws_raise_error(AWS_ERROR_CAL_MALFORMED_ASN1_ENCOUNTERED); - } - } else { - len = len_bytes; - } - - tlv->tag = tag; - tlv->length = len; - tlv->value = (tag == AWS_DER_NULL) ? NULL : cur->ptr; - s_decode_tlv(tlv); - aws_byte_cursor_advance(cur, len); - - return AWS_OP_SUCCESS; -} - -static uint32_t s_encoded_len(struct der_tlv *tlv) { - if (tlv->tag == AWS_DER_INTEGER) { - uint8_t first_byte = tlv->value[0]; - /* if the first byte has the high bit set, a 0 will be prepended to denote unsigned */ - return tlv->length + ((first_byte & 0x80) != 0); - } - if (tlv->tag == AWS_DER_BIT_STRING) { - return tlv->length + 1; /* needs a byte to denote how many trailing skipped bits */ - } - - return tlv->length; -} - -static int s_der_write_tlv(struct der_tlv *tlv, struct aws_byte_buf *buf) { - if (!aws_byte_buf_write_u8(buf, tlv->tag)) { - return aws_raise_error(AWS_ERROR_INVALID_BUFFER_SIZE); - } - uint32_t len = s_encoded_len(tlv); - if (len > UINT16_MAX) { - /* write the high bit plus 4 byte length */ - if (!aws_byte_buf_write_u8(buf, 0x84)) { - return aws_raise_error(AWS_ERROR_INVALID_BUFFER_SIZE); - } - if (!aws_byte_buf_write_be32(buf, len)) { - return aws_raise_error(AWS_ERROR_INVALID_BUFFER_SIZE); - } - } else if (len > UINT8_MAX) { - /* write the high bit plus 2 byte length */ - if (!aws_byte_buf_write_u8(buf, 0x82)) { - return aws_raise_error(AWS_ERROR_INVALID_BUFFER_SIZE); - } - if (!aws_byte_buf_write_be16(buf, (uint16_t)len)) { - return aws_raise_error(AWS_ERROR_INVALID_BUFFER_SIZE); - } - } else if (len > INT8_MAX) { - /* Write the high bit + 1 byte length */ - if (!aws_byte_buf_write_u8(buf, 0x81)) { - return aws_raise_error(AWS_ERROR_INVALID_BUFFER_SIZE); - } - if (!aws_byte_buf_write_u8(buf, (uint8_t)len)) { - return aws_raise_error(AWS_ERROR_INVALID_BUFFER_SIZE); - } - } else { - if (!aws_byte_buf_write_u8(buf, (uint8_t)len)) { - return aws_raise_error(AWS_ERROR_INVALID_BUFFER_SIZE); - } - } - - switch (tlv->tag) { - case AWS_DER_INTEGER: { - /* if the first byte has the sign bit set, insert an extra 0x00 byte to indicate unsigned */ - uint8_t first_byte = tlv->value[0]; - if (first_byte & 0x80) { - if (!aws_byte_buf_write_u8(buf, 0)) { - return aws_raise_error(AWS_ERROR_INVALID_BUFFER_SIZE); - } - } - if (!aws_byte_buf_write(buf, tlv->value, tlv->length)) { - return aws_raise_error(AWS_ERROR_INVALID_BUFFER_SIZE); - } - } break; - case AWS_DER_BOOLEAN: - if (!aws_byte_buf_write_u8(buf, (*tlv->value) ? 0xff : 0x00)) { - return aws_raise_error(AWS_ERROR_INVALID_BUFFER_SIZE); - } - break; - case AWS_DER_BIT_STRING: - /* Write that there are 0 skipped bits */ - if (!aws_byte_buf_write_u8(buf, 0)) { - return aws_raise_error(AWS_ERROR_INVALID_BUFFER_SIZE); - } - /* FALLTHROUGH */ - case AWS_DER_BMPString: - case AWS_DER_IA5String: - case AWS_DER_PrintableString: - case AWS_DER_UTF8_STRING: - case AWS_DER_OBJECT_IDENTIFIER: - case AWS_DER_OCTET_STRING: - case AWS_DER_SEQUENCE: - case AWS_DER_SET: - if (!aws_byte_buf_write(buf, tlv->value, tlv->length)) { - return aws_raise_error(AWS_ERROR_INVALID_BUFFER_SIZE); - } - break; - case AWS_DER_NULL: - /* No value bytes */ - break; - default: - return aws_raise_error(AWS_ERROR_CAL_MISMATCHED_DER_TYPE); - } - - return AWS_OP_SUCCESS; -} - -struct aws_der_encoder *aws_der_encoder_new(struct aws_allocator *allocator, size_t capacity) { - struct aws_der_encoder *encoder = aws_mem_calloc(allocator, 1, sizeof(struct aws_der_encoder)); - AWS_FATAL_ASSERT(encoder); - - encoder->allocator = allocator; - if (aws_byte_buf_init(&encoder->storage, encoder->allocator, capacity)) { - goto error; - } - if (aws_array_list_init_dynamic(&encoder->stack, encoder->allocator, 4, sizeof(struct der_tlv))) { - goto error; - } - - encoder->buffer = &encoder->storage; - return encoder; - -error: - aws_array_list_clean_up(&encoder->stack); - aws_byte_buf_clean_up(&encoder->storage); - aws_mem_release(allocator, encoder); - return NULL; -} - -void aws_der_encoder_destroy(struct aws_der_encoder *encoder) { - if (!encoder) { - return; - } - aws_byte_buf_clean_up_secure(&encoder->storage); - aws_array_list_clean_up(&encoder->stack); - aws_mem_release(encoder->allocator, encoder); -} - -int aws_der_encoder_write_integer(struct aws_der_encoder *encoder, struct aws_byte_cursor integer) { - AWS_FATAL_ASSERT(integer.len <= UINT32_MAX); - struct der_tlv tlv = { - .tag = AWS_DER_INTEGER, - .length = (uint32_t)integer.len, - .value = integer.ptr, - }; - - return s_der_write_tlv(&tlv, encoder->buffer); -} - -int aws_der_encoder_write_boolean(struct aws_der_encoder *encoder, bool boolean) { - struct der_tlv tlv = {.tag = AWS_DER_BOOLEAN, .length = 1, .value = (uint8_t *)&boolean}; - - return s_der_write_tlv(&tlv, encoder->buffer); -} - -int aws_der_encoder_write_null(struct aws_der_encoder *encoder) { - struct der_tlv tlv = { - .tag = AWS_DER_NULL, - .length = 0, - .value = NULL, - }; - - return s_der_write_tlv(&tlv, encoder->buffer); -} - -int aws_der_encoder_write_bit_string(struct aws_der_encoder *encoder, struct aws_byte_cursor bit_string) { - AWS_FATAL_ASSERT(bit_string.len <= UINT32_MAX); - struct der_tlv tlv = { - .tag = AWS_DER_BIT_STRING, - .length = (uint32_t)bit_string.len, - .value = bit_string.ptr, - }; - - return s_der_write_tlv(&tlv, encoder->buffer); -} - -int aws_der_encoder_write_octet_string(struct aws_der_encoder *encoder, struct aws_byte_cursor octet_string) { - AWS_FATAL_ASSERT(octet_string.len <= UINT32_MAX); - struct der_tlv tlv = { - .tag = AWS_DER_OCTET_STRING, - .length = (uint32_t)octet_string.len, - .value = octet_string.ptr, - }; - - return s_der_write_tlv(&tlv, encoder->buffer); -} - -static int s_der_encoder_begin_container(struct aws_der_encoder *encoder, enum aws_der_type type) { - struct aws_byte_buf *seq_buf = aws_mem_acquire(encoder->allocator, sizeof(struct aws_byte_buf)); - AWS_FATAL_ASSERT(seq_buf); - if (aws_byte_buf_init(seq_buf, encoder->allocator, encoder->storage.capacity)) { - return AWS_OP_ERR; - } - struct der_tlv tlv_seq = { - .tag = type, - .length = 0, /* not known yet, will update later */ - .value = (void *)seq_buf, - }; - if (aws_array_list_push_back(&encoder->stack, &tlv_seq)) { - aws_byte_buf_clean_up(seq_buf); - return AWS_OP_ERR; - } - encoder->buffer = seq_buf; - return AWS_OP_SUCCESS; -} - -static int s_der_encoder_end_container(struct aws_der_encoder *encoder) { - struct der_tlv tlv; - if (aws_array_list_back(&encoder->stack, &tlv)) { - return AWS_OP_ERR; - } - aws_array_list_pop_back(&encoder->stack); - /* update the buffer to point at the next container on the stack */ - if (encoder->stack.length > 0) { - struct der_tlv outer; - if (aws_array_list_back(&encoder->stack, &outer)) { - return AWS_OP_ERR; - } - encoder->buffer = (struct aws_byte_buf *)outer.value; - } else { - encoder->buffer = &encoder->storage; - } - - struct aws_byte_buf *seq_buf = (struct aws_byte_buf *)tlv.value; - tlv.length = (uint32_t)seq_buf->len; - tlv.value = seq_buf->buffer; - int result = s_der_write_tlv(&tlv, encoder->buffer); - aws_byte_buf_clean_up_secure(seq_buf); - aws_mem_release(encoder->allocator, seq_buf); - return result; -} - -int aws_der_encoder_begin_sequence(struct aws_der_encoder *encoder) { - return s_der_encoder_begin_container(encoder, AWS_DER_SEQUENCE); -} - -int aws_der_encoder_end_sequence(struct aws_der_encoder *encoder) { - return s_der_encoder_end_container(encoder); -} - -int aws_der_encoder_begin_set(struct aws_der_encoder *encoder) { - return s_der_encoder_begin_container(encoder, AWS_DER_SET); -} - -int aws_der_encoder_end_set(struct aws_der_encoder *encoder) { - return s_der_encoder_end_container(encoder); -} - -int aws_der_encoder_get_contents(struct aws_der_encoder *encoder, struct aws_byte_cursor *contents) { - if (encoder->storage.len == 0) { - return aws_raise_error(AWS_ERROR_INVALID_STATE); - } - if (encoder->buffer != &encoder->storage) { - /* someone forgot to end a sequence or set */ - return aws_raise_error(AWS_ERROR_INVALID_STATE); - } - *contents = aws_byte_cursor_from_buf(&encoder->storage); - return AWS_OP_SUCCESS; -} - -/* - * DECODER - */ -int s_decoder_parse(struct aws_der_decoder *decoder); - -struct aws_der_decoder *aws_der_decoder_new(struct aws_allocator *allocator, struct aws_byte_cursor input) { - struct aws_der_decoder *decoder = aws_mem_calloc(allocator, 1, sizeof(struct aws_der_decoder)); - AWS_FATAL_ASSERT(decoder); - - decoder->allocator = allocator; - decoder->input = input; - decoder->tlv_idx = -1; - decoder->depth = 0; - decoder->container = NULL; - if (aws_array_list_init_dynamic(&decoder->tlvs, decoder->allocator, 16, sizeof(struct der_tlv))) { - goto error; - } - - if (s_decoder_parse(decoder)) { - goto error; - } - - return decoder; - -error: - aws_array_list_clean_up(&decoder->tlvs); - aws_mem_release(allocator, decoder); - return NULL; -} - -void aws_der_decoder_destroy(struct aws_der_decoder *decoder) { - if (!decoder) { - return; - } - aws_array_list_clean_up(&decoder->tlvs); - aws_mem_release(decoder->allocator, decoder); -} - -int s_parse_cursor(struct aws_der_decoder *decoder, struct aws_byte_cursor cur) { - if (++decoder->depth > 16) { - /* stream contains too many nested containers, probably malformed/attack */ - return aws_raise_error(AWS_ERROR_CAL_MALFORMED_ASN1_ENCOUNTERED); - } - - while (cur.len) { - struct der_tlv tlv = {0}; - if (s_der_read_tlv(&cur, &tlv)) { - return aws_raise_error(AWS_ERROR_CAL_MALFORMED_ASN1_ENCOUNTERED); - } - /* skip trailing newlines in the stream after any TLV */ - while (cur.len && *cur.ptr == '\n') { - aws_byte_cursor_advance(&cur, 1); - } - if (aws_array_list_push_back(&decoder->tlvs, &tlv)) { - return aws_raise_error(AWS_ERROR_INVALID_STATE); - } - if (decoder->container) { - decoder->container->count++; - } - /* if the last element was a container, expand it recursively to maintain order */ - if (tlv.tag & AWS_DER_FORM_CONSTRUCTED) { - struct der_tlv *outer_container = decoder->container; - struct der_tlv *container = NULL; - aws_array_list_get_at_ptr(&decoder->tlvs, (void **)&container, decoder->tlvs.length - 1); - decoder->container = container; - - if (!container) { - return aws_raise_error(AWS_ERROR_INVALID_STATE); - } - - struct aws_byte_cursor container_cur = aws_byte_cursor_from_array(container->value, container->length); - if (s_parse_cursor(decoder, container_cur)) { - return aws_raise_error(AWS_ERROR_CAL_MALFORMED_ASN1_ENCOUNTERED); - } - decoder->container = outer_container; /* restore the container stack */ - } - } - - --decoder->depth; - - return AWS_OP_SUCCESS; -} - -int s_decoder_parse(struct aws_der_decoder *decoder) { - return s_parse_cursor(decoder, decoder->input); -} - -bool aws_der_decoder_next(struct aws_der_decoder *decoder) { - return (++decoder->tlv_idx < (int)decoder->tlvs.length); -} - -static struct der_tlv s_decoder_tlv(struct aws_der_decoder *decoder) { - AWS_FATAL_ASSERT(decoder->tlv_idx < (int)decoder->tlvs.length); - struct der_tlv tlv = {0}; - aws_array_list_get_at(&decoder->tlvs, &tlv, decoder->tlv_idx); - return tlv; -} - -enum aws_der_type aws_der_decoder_tlv_type(struct aws_der_decoder *decoder) { - struct der_tlv tlv = s_decoder_tlv(decoder); - return tlv.tag; -} - -size_t aws_der_decoder_tlv_length(struct aws_der_decoder *decoder) { - struct der_tlv tlv = s_decoder_tlv(decoder); - return tlv.length; -} - -size_t aws_der_decoder_tlv_count(struct aws_der_decoder *decoder) { - struct der_tlv tlv = s_decoder_tlv(decoder); - AWS_FATAL_ASSERT(tlv.tag & AWS_DER_FORM_CONSTRUCTED); - return tlv.count; -} - -static void s_tlv_to_blob(struct der_tlv *tlv, struct aws_byte_cursor *blob) { - AWS_FATAL_ASSERT(tlv->tag != AWS_DER_NULL); - *blob = aws_byte_cursor_from_array(tlv->value, tlv->length); -} - -int aws_der_decoder_tlv_string(struct aws_der_decoder *decoder, struct aws_byte_cursor *string) { - struct der_tlv tlv = s_decoder_tlv(decoder); - if (tlv.tag != AWS_DER_OCTET_STRING && tlv.tag != AWS_DER_BIT_STRING) { - return aws_raise_error(AWS_ERROR_CAL_MISMATCHED_DER_TYPE); - } - s_tlv_to_blob(&tlv, string); - return AWS_OP_SUCCESS; -} - -int aws_der_decoder_tlv_integer(struct aws_der_decoder *decoder, struct aws_byte_cursor *integer) { - struct der_tlv tlv = s_decoder_tlv(decoder); - if (tlv.tag != AWS_DER_INTEGER) { - return aws_raise_error(AWS_ERROR_CAL_MISMATCHED_DER_TYPE); - } - s_tlv_to_blob(&tlv, integer); - return AWS_OP_SUCCESS; -} - -int aws_der_decoder_tlv_boolean(struct aws_der_decoder *decoder, bool *boolean) { - struct der_tlv tlv = s_decoder_tlv(decoder); - if (tlv.tag != AWS_DER_BOOLEAN) { - return aws_raise_error(AWS_ERROR_CAL_MISMATCHED_DER_TYPE); - } - *boolean = *tlv.value != 0; - return AWS_OP_SUCCESS; -} - -int aws_der_decoder_tlv_blob(struct aws_der_decoder *decoder, struct aws_byte_cursor *blob) { - struct der_tlv tlv = s_decoder_tlv(decoder); - s_tlv_to_blob(&tlv, blob); - return AWS_OP_SUCCESS; -} - -#ifdef _MSC_VER -# pragma warning(pop) -#endif +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#include <aws/cal/private/der.h> + +#include <aws/cal/cal.h> +#include <aws/common/byte_buf.h> + +#ifdef _MSC_VER +# pragma warning(push) +# pragma warning(disable : 4204 4221) /* non-standard aggregate initializer warnings */ +#endif + +struct aws_der_encoder { + struct aws_allocator *allocator; + struct aws_byte_buf storage; + struct aws_byte_buf *buffer; /* buffer being written to, might be storage, might be a sequence/set buffer */ + struct aws_array_list stack; +}; + +struct aws_der_decoder { + struct aws_allocator *allocator; + struct aws_array_list tlvs; /* parsed elements */ + int tlv_idx; /* index to elements after parsing */ + struct aws_byte_cursor input; /* input buffer */ + uint32_t depth; /* recursion depth when expanding containers */ + struct der_tlv *container; /* currently expanding container */ +}; + +struct der_tlv { + uint8_t tag; + uint32_t length; /* length of value in bytes */ + uint32_t count; /* SEQUENCE or SET element count */ + uint8_t *value; +}; + +static void s_decode_tlv(struct der_tlv *tlv) { + if (tlv->tag == AWS_DER_INTEGER) { + uint8_t first_byte = tlv->value[0]; + /* if the first byte is 0, it just denotes unsigned and should be removed */ + if (first_byte == 0x00) { + tlv->length -= 1; + tlv->value += 1; + } + } else if (tlv->tag == AWS_DER_BIT_STRING) { + /* skip over the trailing skipped bit count */ + tlv->length -= 1; + tlv->value += 1; + } +} + +static int s_der_read_tlv(struct aws_byte_cursor *cur, struct der_tlv *tlv) { + uint8_t tag = 0; + uint8_t len_bytes = 0; + uint32_t len = 0; + if (!aws_byte_cursor_read_u8(cur, &tag)) { + return AWS_OP_ERR; + } + if (!aws_byte_cursor_read_u8(cur, &len_bytes)) { + return AWS_OP_ERR; + } + /* if the sign bit is set, then the first byte is the number of bytes required to store + * the length */ + if (len_bytes & 0x80) { + len_bytes &= 0x7f; + switch (len_bytes) { + case 1: + if (!aws_byte_cursor_read_u8(cur, (uint8_t *)&len)) { + return aws_raise_error(AWS_ERROR_CAL_MALFORMED_ASN1_ENCOUNTERED); + } + break; + case 2: + if (!aws_byte_cursor_read_be16(cur, (uint16_t *)&len)) { + return aws_raise_error(AWS_ERROR_CAL_MALFORMED_ASN1_ENCOUNTERED); + } + break; + case 4: + if (!aws_byte_cursor_read_be32(cur, &len)) { + return aws_raise_error(AWS_ERROR_CAL_MALFORMED_ASN1_ENCOUNTERED); + } + break; + default: + return aws_raise_error(AWS_ERROR_CAL_MALFORMED_ASN1_ENCOUNTERED); + } + } else { + len = len_bytes; + } + + tlv->tag = tag; + tlv->length = len; + tlv->value = (tag == AWS_DER_NULL) ? NULL : cur->ptr; + s_decode_tlv(tlv); + aws_byte_cursor_advance(cur, len); + + return AWS_OP_SUCCESS; +} + +static uint32_t s_encoded_len(struct der_tlv *tlv) { + if (tlv->tag == AWS_DER_INTEGER) { + uint8_t first_byte = tlv->value[0]; + /* if the first byte has the high bit set, a 0 will be prepended to denote unsigned */ + return tlv->length + ((first_byte & 0x80) != 0); + } + if (tlv->tag == AWS_DER_BIT_STRING) { + return tlv->length + 1; /* needs a byte to denote how many trailing skipped bits */ + } + + return tlv->length; +} + +static int s_der_write_tlv(struct der_tlv *tlv, struct aws_byte_buf *buf) { + if (!aws_byte_buf_write_u8(buf, tlv->tag)) { + return aws_raise_error(AWS_ERROR_INVALID_BUFFER_SIZE); + } + uint32_t len = s_encoded_len(tlv); + if (len > UINT16_MAX) { + /* write the high bit plus 4 byte length */ + if (!aws_byte_buf_write_u8(buf, 0x84)) { + return aws_raise_error(AWS_ERROR_INVALID_BUFFER_SIZE); + } + if (!aws_byte_buf_write_be32(buf, len)) { + return aws_raise_error(AWS_ERROR_INVALID_BUFFER_SIZE); + } + } else if (len > UINT8_MAX) { + /* write the high bit plus 2 byte length */ + if (!aws_byte_buf_write_u8(buf, 0x82)) { + return aws_raise_error(AWS_ERROR_INVALID_BUFFER_SIZE); + } + if (!aws_byte_buf_write_be16(buf, (uint16_t)len)) { + return aws_raise_error(AWS_ERROR_INVALID_BUFFER_SIZE); + } + } else if (len > INT8_MAX) { + /* Write the high bit + 1 byte length */ + if (!aws_byte_buf_write_u8(buf, 0x81)) { + return aws_raise_error(AWS_ERROR_INVALID_BUFFER_SIZE); + } + if (!aws_byte_buf_write_u8(buf, (uint8_t)len)) { + return aws_raise_error(AWS_ERROR_INVALID_BUFFER_SIZE); + } + } else { + if (!aws_byte_buf_write_u8(buf, (uint8_t)len)) { + return aws_raise_error(AWS_ERROR_INVALID_BUFFER_SIZE); + } + } + + switch (tlv->tag) { + case AWS_DER_INTEGER: { + /* if the first byte has the sign bit set, insert an extra 0x00 byte to indicate unsigned */ + uint8_t first_byte = tlv->value[0]; + if (first_byte & 0x80) { + if (!aws_byte_buf_write_u8(buf, 0)) { + return aws_raise_error(AWS_ERROR_INVALID_BUFFER_SIZE); + } + } + if (!aws_byte_buf_write(buf, tlv->value, tlv->length)) { + return aws_raise_error(AWS_ERROR_INVALID_BUFFER_SIZE); + } + } break; + case AWS_DER_BOOLEAN: + if (!aws_byte_buf_write_u8(buf, (*tlv->value) ? 0xff : 0x00)) { + return aws_raise_error(AWS_ERROR_INVALID_BUFFER_SIZE); + } + break; + case AWS_DER_BIT_STRING: + /* Write that there are 0 skipped bits */ + if (!aws_byte_buf_write_u8(buf, 0)) { + return aws_raise_error(AWS_ERROR_INVALID_BUFFER_SIZE); + } + /* FALLTHROUGH */ + case AWS_DER_BMPString: + case AWS_DER_IA5String: + case AWS_DER_PrintableString: + case AWS_DER_UTF8_STRING: + case AWS_DER_OBJECT_IDENTIFIER: + case AWS_DER_OCTET_STRING: + case AWS_DER_SEQUENCE: + case AWS_DER_SET: + if (!aws_byte_buf_write(buf, tlv->value, tlv->length)) { + return aws_raise_error(AWS_ERROR_INVALID_BUFFER_SIZE); + } + break; + case AWS_DER_NULL: + /* No value bytes */ + break; + default: + return aws_raise_error(AWS_ERROR_CAL_MISMATCHED_DER_TYPE); + } + + return AWS_OP_SUCCESS; +} + +struct aws_der_encoder *aws_der_encoder_new(struct aws_allocator *allocator, size_t capacity) { + struct aws_der_encoder *encoder = aws_mem_calloc(allocator, 1, sizeof(struct aws_der_encoder)); + AWS_FATAL_ASSERT(encoder); + + encoder->allocator = allocator; + if (aws_byte_buf_init(&encoder->storage, encoder->allocator, capacity)) { + goto error; + } + if (aws_array_list_init_dynamic(&encoder->stack, encoder->allocator, 4, sizeof(struct der_tlv))) { + goto error; + } + + encoder->buffer = &encoder->storage; + return encoder; + +error: + aws_array_list_clean_up(&encoder->stack); + aws_byte_buf_clean_up(&encoder->storage); + aws_mem_release(allocator, encoder); + return NULL; +} + +void aws_der_encoder_destroy(struct aws_der_encoder *encoder) { + if (!encoder) { + return; + } + aws_byte_buf_clean_up_secure(&encoder->storage); + aws_array_list_clean_up(&encoder->stack); + aws_mem_release(encoder->allocator, encoder); +} + +int aws_der_encoder_write_integer(struct aws_der_encoder *encoder, struct aws_byte_cursor integer) { + AWS_FATAL_ASSERT(integer.len <= UINT32_MAX); + struct der_tlv tlv = { + .tag = AWS_DER_INTEGER, + .length = (uint32_t)integer.len, + .value = integer.ptr, + }; + + return s_der_write_tlv(&tlv, encoder->buffer); +} + +int aws_der_encoder_write_boolean(struct aws_der_encoder *encoder, bool boolean) { + struct der_tlv tlv = {.tag = AWS_DER_BOOLEAN, .length = 1, .value = (uint8_t *)&boolean}; + + return s_der_write_tlv(&tlv, encoder->buffer); +} + +int aws_der_encoder_write_null(struct aws_der_encoder *encoder) { + struct der_tlv tlv = { + .tag = AWS_DER_NULL, + .length = 0, + .value = NULL, + }; + + return s_der_write_tlv(&tlv, encoder->buffer); +} + +int aws_der_encoder_write_bit_string(struct aws_der_encoder *encoder, struct aws_byte_cursor bit_string) { + AWS_FATAL_ASSERT(bit_string.len <= UINT32_MAX); + struct der_tlv tlv = { + .tag = AWS_DER_BIT_STRING, + .length = (uint32_t)bit_string.len, + .value = bit_string.ptr, + }; + + return s_der_write_tlv(&tlv, encoder->buffer); +} + +int aws_der_encoder_write_octet_string(struct aws_der_encoder *encoder, struct aws_byte_cursor octet_string) { + AWS_FATAL_ASSERT(octet_string.len <= UINT32_MAX); + struct der_tlv tlv = { + .tag = AWS_DER_OCTET_STRING, + .length = (uint32_t)octet_string.len, + .value = octet_string.ptr, + }; + + return s_der_write_tlv(&tlv, encoder->buffer); +} + +static int s_der_encoder_begin_container(struct aws_der_encoder *encoder, enum aws_der_type type) { + struct aws_byte_buf *seq_buf = aws_mem_acquire(encoder->allocator, sizeof(struct aws_byte_buf)); + AWS_FATAL_ASSERT(seq_buf); + if (aws_byte_buf_init(seq_buf, encoder->allocator, encoder->storage.capacity)) { + return AWS_OP_ERR; + } + struct der_tlv tlv_seq = { + .tag = type, + .length = 0, /* not known yet, will update later */ + .value = (void *)seq_buf, + }; + if (aws_array_list_push_back(&encoder->stack, &tlv_seq)) { + aws_byte_buf_clean_up(seq_buf); + return AWS_OP_ERR; + } + encoder->buffer = seq_buf; + return AWS_OP_SUCCESS; +} + +static int s_der_encoder_end_container(struct aws_der_encoder *encoder) { + struct der_tlv tlv; + if (aws_array_list_back(&encoder->stack, &tlv)) { + return AWS_OP_ERR; + } + aws_array_list_pop_back(&encoder->stack); + /* update the buffer to point at the next container on the stack */ + if (encoder->stack.length > 0) { + struct der_tlv outer; + if (aws_array_list_back(&encoder->stack, &outer)) { + return AWS_OP_ERR; + } + encoder->buffer = (struct aws_byte_buf *)outer.value; + } else { + encoder->buffer = &encoder->storage; + } + + struct aws_byte_buf *seq_buf = (struct aws_byte_buf *)tlv.value; + tlv.length = (uint32_t)seq_buf->len; + tlv.value = seq_buf->buffer; + int result = s_der_write_tlv(&tlv, encoder->buffer); + aws_byte_buf_clean_up_secure(seq_buf); + aws_mem_release(encoder->allocator, seq_buf); + return result; +} + +int aws_der_encoder_begin_sequence(struct aws_der_encoder *encoder) { + return s_der_encoder_begin_container(encoder, AWS_DER_SEQUENCE); +} + +int aws_der_encoder_end_sequence(struct aws_der_encoder *encoder) { + return s_der_encoder_end_container(encoder); +} + +int aws_der_encoder_begin_set(struct aws_der_encoder *encoder) { + return s_der_encoder_begin_container(encoder, AWS_DER_SET); +} + +int aws_der_encoder_end_set(struct aws_der_encoder *encoder) { + return s_der_encoder_end_container(encoder); +} + +int aws_der_encoder_get_contents(struct aws_der_encoder *encoder, struct aws_byte_cursor *contents) { + if (encoder->storage.len == 0) { + return aws_raise_error(AWS_ERROR_INVALID_STATE); + } + if (encoder->buffer != &encoder->storage) { + /* someone forgot to end a sequence or set */ + return aws_raise_error(AWS_ERROR_INVALID_STATE); + } + *contents = aws_byte_cursor_from_buf(&encoder->storage); + return AWS_OP_SUCCESS; +} + +/* + * DECODER + */ +int s_decoder_parse(struct aws_der_decoder *decoder); + +struct aws_der_decoder *aws_der_decoder_new(struct aws_allocator *allocator, struct aws_byte_cursor input) { + struct aws_der_decoder *decoder = aws_mem_calloc(allocator, 1, sizeof(struct aws_der_decoder)); + AWS_FATAL_ASSERT(decoder); + + decoder->allocator = allocator; + decoder->input = input; + decoder->tlv_idx = -1; + decoder->depth = 0; + decoder->container = NULL; + if (aws_array_list_init_dynamic(&decoder->tlvs, decoder->allocator, 16, sizeof(struct der_tlv))) { + goto error; + } + + if (s_decoder_parse(decoder)) { + goto error; + } + + return decoder; + +error: + aws_array_list_clean_up(&decoder->tlvs); + aws_mem_release(allocator, decoder); + return NULL; +} + +void aws_der_decoder_destroy(struct aws_der_decoder *decoder) { + if (!decoder) { + return; + } + aws_array_list_clean_up(&decoder->tlvs); + aws_mem_release(decoder->allocator, decoder); +} + +int s_parse_cursor(struct aws_der_decoder *decoder, struct aws_byte_cursor cur) { + if (++decoder->depth > 16) { + /* stream contains too many nested containers, probably malformed/attack */ + return aws_raise_error(AWS_ERROR_CAL_MALFORMED_ASN1_ENCOUNTERED); + } + + while (cur.len) { + struct der_tlv tlv = {0}; + if (s_der_read_tlv(&cur, &tlv)) { + return aws_raise_error(AWS_ERROR_CAL_MALFORMED_ASN1_ENCOUNTERED); + } + /* skip trailing newlines in the stream after any TLV */ + while (cur.len && *cur.ptr == '\n') { + aws_byte_cursor_advance(&cur, 1); + } + if (aws_array_list_push_back(&decoder->tlvs, &tlv)) { + return aws_raise_error(AWS_ERROR_INVALID_STATE); + } + if (decoder->container) { + decoder->container->count++; + } + /* if the last element was a container, expand it recursively to maintain order */ + if (tlv.tag & AWS_DER_FORM_CONSTRUCTED) { + struct der_tlv *outer_container = decoder->container; + struct der_tlv *container = NULL; + aws_array_list_get_at_ptr(&decoder->tlvs, (void **)&container, decoder->tlvs.length - 1); + decoder->container = container; + + if (!container) { + return aws_raise_error(AWS_ERROR_INVALID_STATE); + } + + struct aws_byte_cursor container_cur = aws_byte_cursor_from_array(container->value, container->length); + if (s_parse_cursor(decoder, container_cur)) { + return aws_raise_error(AWS_ERROR_CAL_MALFORMED_ASN1_ENCOUNTERED); + } + decoder->container = outer_container; /* restore the container stack */ + } + } + + --decoder->depth; + + return AWS_OP_SUCCESS; +} + +int s_decoder_parse(struct aws_der_decoder *decoder) { + return s_parse_cursor(decoder, decoder->input); +} + +bool aws_der_decoder_next(struct aws_der_decoder *decoder) { + return (++decoder->tlv_idx < (int)decoder->tlvs.length); +} + +static struct der_tlv s_decoder_tlv(struct aws_der_decoder *decoder) { + AWS_FATAL_ASSERT(decoder->tlv_idx < (int)decoder->tlvs.length); + struct der_tlv tlv = {0}; + aws_array_list_get_at(&decoder->tlvs, &tlv, decoder->tlv_idx); + return tlv; +} + +enum aws_der_type aws_der_decoder_tlv_type(struct aws_der_decoder *decoder) { + struct der_tlv tlv = s_decoder_tlv(decoder); + return tlv.tag; +} + +size_t aws_der_decoder_tlv_length(struct aws_der_decoder *decoder) { + struct der_tlv tlv = s_decoder_tlv(decoder); + return tlv.length; +} + +size_t aws_der_decoder_tlv_count(struct aws_der_decoder *decoder) { + struct der_tlv tlv = s_decoder_tlv(decoder); + AWS_FATAL_ASSERT(tlv.tag & AWS_DER_FORM_CONSTRUCTED); + return tlv.count; +} + +static void s_tlv_to_blob(struct der_tlv *tlv, struct aws_byte_cursor *blob) { + AWS_FATAL_ASSERT(tlv->tag != AWS_DER_NULL); + *blob = aws_byte_cursor_from_array(tlv->value, tlv->length); +} + +int aws_der_decoder_tlv_string(struct aws_der_decoder *decoder, struct aws_byte_cursor *string) { + struct der_tlv tlv = s_decoder_tlv(decoder); + if (tlv.tag != AWS_DER_OCTET_STRING && tlv.tag != AWS_DER_BIT_STRING) { + return aws_raise_error(AWS_ERROR_CAL_MISMATCHED_DER_TYPE); + } + s_tlv_to_blob(&tlv, string); + return AWS_OP_SUCCESS; +} + +int aws_der_decoder_tlv_integer(struct aws_der_decoder *decoder, struct aws_byte_cursor *integer) { + struct der_tlv tlv = s_decoder_tlv(decoder); + if (tlv.tag != AWS_DER_INTEGER) { + return aws_raise_error(AWS_ERROR_CAL_MISMATCHED_DER_TYPE); + } + s_tlv_to_blob(&tlv, integer); + return AWS_OP_SUCCESS; +} + +int aws_der_decoder_tlv_boolean(struct aws_der_decoder *decoder, bool *boolean) { + struct der_tlv tlv = s_decoder_tlv(decoder); + if (tlv.tag != AWS_DER_BOOLEAN) { + return aws_raise_error(AWS_ERROR_CAL_MISMATCHED_DER_TYPE); + } + *boolean = *tlv.value != 0; + return AWS_OP_SUCCESS; +} + +int aws_der_decoder_tlv_blob(struct aws_der_decoder *decoder, struct aws_byte_cursor *blob) { + struct der_tlv tlv = s_decoder_tlv(decoder); + s_tlv_to_blob(&tlv, blob); + return AWS_OP_SUCCESS; +} + +#ifdef _MSC_VER +# pragma warning(pop) +#endif diff --git a/contrib/restricted/aws/aws-c-cal/source/ecc.c b/contrib/restricted/aws/aws-c-cal/source/ecc.c index 40a78d59c9..d4e65fda64 100644 --- a/contrib/restricted/aws/aws-c-cal/source/ecc.c +++ b/contrib/restricted/aws/aws-c-cal/source/ecc.c @@ -1,269 +1,269 @@ -/** - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0. - */ -#include <aws/cal/private/ecc.h> - -#include <aws/cal/cal.h> -#include <aws/cal/private/der.h> -#include <aws/common/encoding.h> - -#define STATIC_INIT_BYTE_CURSOR(a, name) \ - static struct aws_byte_cursor s_##name = { \ - .ptr = (a), \ - .len = sizeof(a), \ - }; - -static uint8_t s_p256_oid[] = { - 0x2A, - 0x86, - 0x48, - 0xCE, - 0x3D, - 0x03, - 0x01, - 0x07, -}; -STATIC_INIT_BYTE_CURSOR(s_p256_oid, ecc_p256_oid) - -static uint8_t s_p384_oid[] = { - 0x2B, - 0x81, - 0x04, - 0x00, - 0x22, -}; -STATIC_INIT_BYTE_CURSOR(s_p384_oid, ecc_p384_oid) - -static struct aws_byte_cursor *s_ecc_curve_oids[] = { - [AWS_CAL_ECDSA_P256] = &s_ecc_p256_oid, - [AWS_CAL_ECDSA_P384] = &s_ecc_p384_oid, -}; - -int aws_ecc_curve_name_from_oid(struct aws_byte_cursor *oid, enum aws_ecc_curve_name *curve_name) { - if (aws_byte_cursor_eq(oid, &s_ecc_p256_oid)) { - *curve_name = AWS_CAL_ECDSA_P256; - return AWS_OP_SUCCESS; - } - - if (aws_byte_cursor_eq(oid, &s_ecc_p384_oid)) { - *curve_name = AWS_CAL_ECDSA_P384; - return AWS_OP_SUCCESS; - } - - return aws_raise_error(AWS_ERROR_CAL_UNKNOWN_OBJECT_IDENTIFIER); -} - -int aws_ecc_oid_from_curve_name(enum aws_ecc_curve_name curve_name, struct aws_byte_cursor *oid) { - if (curve_name < AWS_CAL_ECDSA_P256 || curve_name > AWS_CAL_ECDSA_P384) { - return aws_raise_error(AWS_ERROR_CAL_UNSUPPORTED_ALGORITHM); - } - *oid = *s_ecc_curve_oids[curve_name]; - return AWS_OP_SUCCESS; -} - -static void s_aws_ecc_key_pair_destroy(struct aws_ecc_key_pair *key_pair) { - if (key_pair) { - AWS_FATAL_ASSERT(key_pair->vtable->destroy && "ECC KEY PAIR destroy function must be included on the vtable"); - key_pair->vtable->destroy(key_pair); - } -} - -int aws_ecc_key_pair_derive_public_key(struct aws_ecc_key_pair *key_pair) { - AWS_FATAL_ASSERT(key_pair->vtable->derive_pub_key && "ECC KEY PAIR derive function must be included on the vtable"); - return key_pair->vtable->derive_pub_key(key_pair); -} - -int aws_ecc_key_pair_sign_message( - const struct aws_ecc_key_pair *key_pair, - const struct aws_byte_cursor *message, - struct aws_byte_buf *signature) { - AWS_FATAL_ASSERT(key_pair->vtable->sign_message && "ECC KEY PAIR sign message must be included on the vtable"); - return key_pair->vtable->sign_message(key_pair, message, signature); -} - -int aws_ecc_key_pair_verify_signature( - const struct aws_ecc_key_pair *key_pair, - const struct aws_byte_cursor *message, - const struct aws_byte_cursor *signature) { - AWS_FATAL_ASSERT( - key_pair->vtable->verify_signature && "ECC KEY PAIR verify signature must be included on the vtable"); - return key_pair->vtable->verify_signature(key_pair, message, signature); -} - -size_t aws_ecc_key_pair_signature_length(const struct aws_ecc_key_pair *key_pair) { - AWS_FATAL_ASSERT( - key_pair->vtable->signature_length && "ECC KEY PAIR signature length must be included on the vtable"); - return key_pair->vtable->signature_length(key_pair); -} - -void aws_ecc_key_pair_get_public_key( - const struct aws_ecc_key_pair *key_pair, - struct aws_byte_cursor *pub_x, - struct aws_byte_cursor *pub_y) { - *pub_x = aws_byte_cursor_from_buf(&key_pair->pub_x); - *pub_y = aws_byte_cursor_from_buf(&key_pair->pub_y); -} - -void aws_ecc_key_pair_get_private_key(const struct aws_ecc_key_pair *key_pair, struct aws_byte_cursor *private_d) { - *private_d = aws_byte_cursor_from_buf(&key_pair->priv_d); -} - -size_t aws_ecc_key_coordinate_byte_size_from_curve_name(enum aws_ecc_curve_name curve_name) { - switch (curve_name) { - case AWS_CAL_ECDSA_P256: - return 32; - case AWS_CAL_ECDSA_P384: - return 48; - default: - return 0; - } -} - -int aws_der_decoder_load_ecc_key_pair( - struct aws_der_decoder *decoder, - struct aws_byte_cursor *out_public_x_coor, - struct aws_byte_cursor *out_public_y_coor, - struct aws_byte_cursor *out_private_d, - enum aws_ecc_curve_name *out_curve_name) { - - AWS_ZERO_STRUCT(*out_public_x_coor); - AWS_ZERO_STRUCT(*out_public_y_coor); - AWS_ZERO_STRUCT(*out_private_d); - - /* we could have private key or a public key, or a full pair. */ - struct aws_byte_cursor pair_part_1; - AWS_ZERO_STRUCT(pair_part_1); - struct aws_byte_cursor pair_part_2; - AWS_ZERO_STRUCT(pair_part_2); - - bool curve_name_recognized = false; - - /* work with this pointer and move it to the next after using it. We need - * to know which curve we're dealing with before we can figure out which is which. */ - struct aws_byte_cursor *current_part = &pair_part_1; - - while (aws_der_decoder_next(decoder)) { - enum aws_der_type type = aws_der_decoder_tlv_type(decoder); - - if (type == AWS_DER_OBJECT_IDENTIFIER) { - struct aws_byte_cursor oid; - AWS_ZERO_STRUCT(oid); - aws_der_decoder_tlv_blob(decoder, &oid); - /* There can be other OID's so just look for one that is the curve. */ - if (!aws_ecc_curve_name_from_oid(&oid, out_curve_name)) { - curve_name_recognized = true; - } - continue; - } - - /* you'd think we'd get some type hints on which key this is, but it's not consistent - * as far as I can tell. */ - if (type == AWS_DER_BIT_STRING || type == AWS_DER_OCTET_STRING) { - aws_der_decoder_tlv_string(decoder, current_part); - current_part = &pair_part_2; - } - } - - if (!curve_name_recognized) { - return aws_raise_error(AWS_ERROR_CAL_UNKNOWN_OBJECT_IDENTIFIER); - } - - size_t key_coordinate_size = aws_ecc_key_coordinate_byte_size_from_curve_name(*out_curve_name); - - struct aws_byte_cursor *private_key = NULL; - struct aws_byte_cursor *public_key = NULL; - - size_t public_key_blob_size = key_coordinate_size * 2 + 1; - - if (pair_part_1.ptr && pair_part_1.len) { - if (pair_part_1.len == key_coordinate_size) { - private_key = &pair_part_1; - } else if (pair_part_1.len == public_key_blob_size) { - public_key = &pair_part_1; - } - } - - if (pair_part_2.ptr && pair_part_2.len) { - if (pair_part_2.len == key_coordinate_size) { - private_key = &pair_part_2; - } else if (pair_part_2.len == public_key_blob_size) { - public_key = &pair_part_2; - } - } - - if (!private_key && !public_key) { - return aws_raise_error(AWS_ERROR_CAL_MISSING_REQUIRED_KEY_COMPONENT); - } - - if (private_key) { - *out_private_d = *private_key; - } - - if (public_key) { - aws_byte_cursor_advance(public_key, 1); - *out_public_x_coor = *public_key; - out_public_x_coor->len = key_coordinate_size; - out_public_y_coor->ptr = public_key->ptr + key_coordinate_size; - out_public_y_coor->len = key_coordinate_size; - } - - return AWS_OP_SUCCESS; -} - -void aws_ecc_key_pair_acquire(struct aws_ecc_key_pair *key_pair) { - aws_atomic_fetch_add(&key_pair->ref_count, 1); -} - -void aws_ecc_key_pair_release(struct aws_ecc_key_pair *key_pair) { - if (key_pair == NULL) { - return; - } - - size_t old_value = aws_atomic_fetch_sub(&key_pair->ref_count, 1); - - if (old_value == 1) { - s_aws_ecc_key_pair_destroy(key_pair); - } -} - -struct aws_ecc_key_pair *aws_ecc_key_new_from_hex_coordinates( - struct aws_allocator *allocator, - enum aws_ecc_curve_name curve_name, - struct aws_byte_cursor pub_x_hex_cursor, - struct aws_byte_cursor pub_y_hex_cursor) { - struct aws_byte_buf pub_x_buffer; - AWS_ZERO_STRUCT(pub_x_buffer); - struct aws_byte_buf pub_y_buffer; - AWS_ZERO_STRUCT(pub_y_buffer); - - struct aws_ecc_key_pair *key = NULL; - - size_t pub_x_length = 0; - size_t pub_y_length = 0; - if (aws_hex_compute_decoded_len(pub_x_hex_cursor.len, &pub_x_length) || - aws_hex_compute_decoded_len(pub_y_hex_cursor.len, &pub_y_length)) { - goto done; - } - - if (aws_byte_buf_init(&pub_x_buffer, allocator, pub_x_length) || - aws_byte_buf_init(&pub_y_buffer, allocator, pub_y_length)) { - goto done; - } - - if (aws_hex_decode(&pub_x_hex_cursor, &pub_x_buffer) || aws_hex_decode(&pub_y_hex_cursor, &pub_y_buffer)) { - goto done; - } - - struct aws_byte_cursor pub_x_cursor = aws_byte_cursor_from_buf(&pub_x_buffer); - struct aws_byte_cursor pub_y_cursor = aws_byte_cursor_from_buf(&pub_y_buffer); - - key = aws_ecc_key_pair_new_from_public_key(allocator, curve_name, &pub_x_cursor, &pub_y_cursor); - -done: - - aws_byte_buf_clean_up(&pub_x_buffer); - aws_byte_buf_clean_up(&pub_y_buffer); - - return key; -} +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ +#include <aws/cal/private/ecc.h> + +#include <aws/cal/cal.h> +#include <aws/cal/private/der.h> +#include <aws/common/encoding.h> + +#define STATIC_INIT_BYTE_CURSOR(a, name) \ + static struct aws_byte_cursor s_##name = { \ + .ptr = (a), \ + .len = sizeof(a), \ + }; + +static uint8_t s_p256_oid[] = { + 0x2A, + 0x86, + 0x48, + 0xCE, + 0x3D, + 0x03, + 0x01, + 0x07, +}; +STATIC_INIT_BYTE_CURSOR(s_p256_oid, ecc_p256_oid) + +static uint8_t s_p384_oid[] = { + 0x2B, + 0x81, + 0x04, + 0x00, + 0x22, +}; +STATIC_INIT_BYTE_CURSOR(s_p384_oid, ecc_p384_oid) + +static struct aws_byte_cursor *s_ecc_curve_oids[] = { + [AWS_CAL_ECDSA_P256] = &s_ecc_p256_oid, + [AWS_CAL_ECDSA_P384] = &s_ecc_p384_oid, +}; + +int aws_ecc_curve_name_from_oid(struct aws_byte_cursor *oid, enum aws_ecc_curve_name *curve_name) { + if (aws_byte_cursor_eq(oid, &s_ecc_p256_oid)) { + *curve_name = AWS_CAL_ECDSA_P256; + return AWS_OP_SUCCESS; + } + + if (aws_byte_cursor_eq(oid, &s_ecc_p384_oid)) { + *curve_name = AWS_CAL_ECDSA_P384; + return AWS_OP_SUCCESS; + } + + return aws_raise_error(AWS_ERROR_CAL_UNKNOWN_OBJECT_IDENTIFIER); +} + +int aws_ecc_oid_from_curve_name(enum aws_ecc_curve_name curve_name, struct aws_byte_cursor *oid) { + if (curve_name < AWS_CAL_ECDSA_P256 || curve_name > AWS_CAL_ECDSA_P384) { + return aws_raise_error(AWS_ERROR_CAL_UNSUPPORTED_ALGORITHM); + } + *oid = *s_ecc_curve_oids[curve_name]; + return AWS_OP_SUCCESS; +} + +static void s_aws_ecc_key_pair_destroy(struct aws_ecc_key_pair *key_pair) { + if (key_pair) { + AWS_FATAL_ASSERT(key_pair->vtable->destroy && "ECC KEY PAIR destroy function must be included on the vtable"); + key_pair->vtable->destroy(key_pair); + } +} + +int aws_ecc_key_pair_derive_public_key(struct aws_ecc_key_pair *key_pair) { + AWS_FATAL_ASSERT(key_pair->vtable->derive_pub_key && "ECC KEY PAIR derive function must be included on the vtable"); + return key_pair->vtable->derive_pub_key(key_pair); +} + +int aws_ecc_key_pair_sign_message( + const struct aws_ecc_key_pair *key_pair, + const struct aws_byte_cursor *message, + struct aws_byte_buf *signature) { + AWS_FATAL_ASSERT(key_pair->vtable->sign_message && "ECC KEY PAIR sign message must be included on the vtable"); + return key_pair->vtable->sign_message(key_pair, message, signature); +} + +int aws_ecc_key_pair_verify_signature( + const struct aws_ecc_key_pair *key_pair, + const struct aws_byte_cursor *message, + const struct aws_byte_cursor *signature) { + AWS_FATAL_ASSERT( + key_pair->vtable->verify_signature && "ECC KEY PAIR verify signature must be included on the vtable"); + return key_pair->vtable->verify_signature(key_pair, message, signature); +} + +size_t aws_ecc_key_pair_signature_length(const struct aws_ecc_key_pair *key_pair) { + AWS_FATAL_ASSERT( + key_pair->vtable->signature_length && "ECC KEY PAIR signature length must be included on the vtable"); + return key_pair->vtable->signature_length(key_pair); +} + +void aws_ecc_key_pair_get_public_key( + const struct aws_ecc_key_pair *key_pair, + struct aws_byte_cursor *pub_x, + struct aws_byte_cursor *pub_y) { + *pub_x = aws_byte_cursor_from_buf(&key_pair->pub_x); + *pub_y = aws_byte_cursor_from_buf(&key_pair->pub_y); +} + +void aws_ecc_key_pair_get_private_key(const struct aws_ecc_key_pair *key_pair, struct aws_byte_cursor *private_d) { + *private_d = aws_byte_cursor_from_buf(&key_pair->priv_d); +} + +size_t aws_ecc_key_coordinate_byte_size_from_curve_name(enum aws_ecc_curve_name curve_name) { + switch (curve_name) { + case AWS_CAL_ECDSA_P256: + return 32; + case AWS_CAL_ECDSA_P384: + return 48; + default: + return 0; + } +} + +int aws_der_decoder_load_ecc_key_pair( + struct aws_der_decoder *decoder, + struct aws_byte_cursor *out_public_x_coor, + struct aws_byte_cursor *out_public_y_coor, + struct aws_byte_cursor *out_private_d, + enum aws_ecc_curve_name *out_curve_name) { + + AWS_ZERO_STRUCT(*out_public_x_coor); + AWS_ZERO_STRUCT(*out_public_y_coor); + AWS_ZERO_STRUCT(*out_private_d); + + /* we could have private key or a public key, or a full pair. */ + struct aws_byte_cursor pair_part_1; + AWS_ZERO_STRUCT(pair_part_1); + struct aws_byte_cursor pair_part_2; + AWS_ZERO_STRUCT(pair_part_2); + + bool curve_name_recognized = false; + + /* work with this pointer and move it to the next after using it. We need + * to know which curve we're dealing with before we can figure out which is which. */ + struct aws_byte_cursor *current_part = &pair_part_1; + + while (aws_der_decoder_next(decoder)) { + enum aws_der_type type = aws_der_decoder_tlv_type(decoder); + + if (type == AWS_DER_OBJECT_IDENTIFIER) { + struct aws_byte_cursor oid; + AWS_ZERO_STRUCT(oid); + aws_der_decoder_tlv_blob(decoder, &oid); + /* There can be other OID's so just look for one that is the curve. */ + if (!aws_ecc_curve_name_from_oid(&oid, out_curve_name)) { + curve_name_recognized = true; + } + continue; + } + + /* you'd think we'd get some type hints on which key this is, but it's not consistent + * as far as I can tell. */ + if (type == AWS_DER_BIT_STRING || type == AWS_DER_OCTET_STRING) { + aws_der_decoder_tlv_string(decoder, current_part); + current_part = &pair_part_2; + } + } + + if (!curve_name_recognized) { + return aws_raise_error(AWS_ERROR_CAL_UNKNOWN_OBJECT_IDENTIFIER); + } + + size_t key_coordinate_size = aws_ecc_key_coordinate_byte_size_from_curve_name(*out_curve_name); + + struct aws_byte_cursor *private_key = NULL; + struct aws_byte_cursor *public_key = NULL; + + size_t public_key_blob_size = key_coordinate_size * 2 + 1; + + if (pair_part_1.ptr && pair_part_1.len) { + if (pair_part_1.len == key_coordinate_size) { + private_key = &pair_part_1; + } else if (pair_part_1.len == public_key_blob_size) { + public_key = &pair_part_1; + } + } + + if (pair_part_2.ptr && pair_part_2.len) { + if (pair_part_2.len == key_coordinate_size) { + private_key = &pair_part_2; + } else if (pair_part_2.len == public_key_blob_size) { + public_key = &pair_part_2; + } + } + + if (!private_key && !public_key) { + return aws_raise_error(AWS_ERROR_CAL_MISSING_REQUIRED_KEY_COMPONENT); + } + + if (private_key) { + *out_private_d = *private_key; + } + + if (public_key) { + aws_byte_cursor_advance(public_key, 1); + *out_public_x_coor = *public_key; + out_public_x_coor->len = key_coordinate_size; + out_public_y_coor->ptr = public_key->ptr + key_coordinate_size; + out_public_y_coor->len = key_coordinate_size; + } + + return AWS_OP_SUCCESS; +} + +void aws_ecc_key_pair_acquire(struct aws_ecc_key_pair *key_pair) { + aws_atomic_fetch_add(&key_pair->ref_count, 1); +} + +void aws_ecc_key_pair_release(struct aws_ecc_key_pair *key_pair) { + if (key_pair == NULL) { + return; + } + + size_t old_value = aws_atomic_fetch_sub(&key_pair->ref_count, 1); + + if (old_value == 1) { + s_aws_ecc_key_pair_destroy(key_pair); + } +} + +struct aws_ecc_key_pair *aws_ecc_key_new_from_hex_coordinates( + struct aws_allocator *allocator, + enum aws_ecc_curve_name curve_name, + struct aws_byte_cursor pub_x_hex_cursor, + struct aws_byte_cursor pub_y_hex_cursor) { + struct aws_byte_buf pub_x_buffer; + AWS_ZERO_STRUCT(pub_x_buffer); + struct aws_byte_buf pub_y_buffer; + AWS_ZERO_STRUCT(pub_y_buffer); + + struct aws_ecc_key_pair *key = NULL; + + size_t pub_x_length = 0; + size_t pub_y_length = 0; + if (aws_hex_compute_decoded_len(pub_x_hex_cursor.len, &pub_x_length) || + aws_hex_compute_decoded_len(pub_y_hex_cursor.len, &pub_y_length)) { + goto done; + } + + if (aws_byte_buf_init(&pub_x_buffer, allocator, pub_x_length) || + aws_byte_buf_init(&pub_y_buffer, allocator, pub_y_length)) { + goto done; + } + + if (aws_hex_decode(&pub_x_hex_cursor, &pub_x_buffer) || aws_hex_decode(&pub_y_hex_cursor, &pub_y_buffer)) { + goto done; + } + + struct aws_byte_cursor pub_x_cursor = aws_byte_cursor_from_buf(&pub_x_buffer); + struct aws_byte_cursor pub_y_cursor = aws_byte_cursor_from_buf(&pub_y_buffer); + + key = aws_ecc_key_pair_new_from_public_key(allocator, curve_name, &pub_x_cursor, &pub_y_cursor); + +done: + + aws_byte_buf_clean_up(&pub_x_buffer); + aws_byte_buf_clean_up(&pub_y_buffer); + + return key; +} diff --git a/contrib/restricted/aws/aws-c-cal/source/hash.c b/contrib/restricted/aws/aws-c-cal/source/hash.c index b4a9163fc4..9a797cf1a5 100644 --- a/contrib/restricted/aws/aws-c-cal/source/hash.c +++ b/contrib/restricted/aws/aws-c-cal/source/hash.c @@ -1,110 +1,110 @@ -/** - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0. - */ -#include <aws/cal/hash.h> - -#ifndef AWS_BYO_CRYPTO -extern struct aws_hash *aws_sha256_default_new(struct aws_allocator *allocator); -extern struct aws_hash *aws_md5_default_new(struct aws_allocator *allocator); - -static aws_hash_new_fn *s_sha256_new_fn = aws_sha256_default_new; -static aws_hash_new_fn *s_md5_new_fn = aws_md5_default_new; -#else -static struct aws_hash *aws_hash_new_abort(struct aws_allocator *allocator) { - (void)allocator; - abort(); -} - -static aws_hash_new_fn *s_sha256_new_fn = aws_hash_new_abort; -static aws_hash_new_fn *s_md5_new_fn = aws_hash_new_abort; -#endif - -struct aws_hash *aws_sha256_new(struct aws_allocator *allocator) { - return s_sha256_new_fn(allocator); -} - -struct aws_hash *aws_md5_new(struct aws_allocator *allocator) { - return s_md5_new_fn(allocator); -} - -void aws_set_md5_new_fn(aws_hash_new_fn *fn) { - s_md5_new_fn = fn; -} - -void aws_set_sha256_new_fn(aws_hash_new_fn *fn) { - s_sha256_new_fn = fn; -} - -void aws_hash_destroy(struct aws_hash *hash) { - hash->vtable->destroy(hash); -} - -int aws_hash_update(struct aws_hash *hash, const struct aws_byte_cursor *to_hash) { - return hash->vtable->update(hash, to_hash); -} - -int aws_hash_finalize(struct aws_hash *hash, struct aws_byte_buf *output, size_t truncate_to) { - - if (truncate_to && truncate_to < hash->digest_size) { - size_t available_buffer = output->capacity - output->len; - if (available_buffer < truncate_to) { - return aws_raise_error(AWS_ERROR_SHORT_BUFFER); - } - - uint8_t tmp_output[128] = {0}; - AWS_ASSERT(sizeof(tmp_output) >= hash->digest_size); - - struct aws_byte_buf tmp_out_buf = aws_byte_buf_from_array(tmp_output, sizeof(tmp_output)); - tmp_out_buf.len = 0; - - if (hash->vtable->finalize(hash, &tmp_out_buf)) { - return AWS_OP_ERR; - } - - memcpy(output->buffer + output->len, tmp_output, truncate_to); - output->len += truncate_to; - return AWS_OP_SUCCESS; - } - - return hash->vtable->finalize(hash, output); -} - -static inline int compute_hash( - struct aws_hash *hash, - const struct aws_byte_cursor *input, - struct aws_byte_buf *output, - size_t truncate_to) { - if (!hash) { - return AWS_OP_ERR; - } - - if (aws_hash_update(hash, input)) { - aws_hash_destroy(hash); - return AWS_OP_ERR; - } - - if (aws_hash_finalize(hash, output, truncate_to)) { - aws_hash_destroy(hash); - return AWS_OP_ERR; - } - - aws_hash_destroy(hash); - return AWS_OP_SUCCESS; -} - -int aws_md5_compute( - struct aws_allocator *allocator, - const struct aws_byte_cursor *input, - struct aws_byte_buf *output, - size_t truncate_to) { - return compute_hash(aws_md5_new(allocator), input, output, truncate_to); -} - -int aws_sha256_compute( - struct aws_allocator *allocator, - const struct aws_byte_cursor *input, - struct aws_byte_buf *output, - size_t truncate_to) { - return compute_hash(aws_sha256_new(allocator), input, output, truncate_to); -} +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ +#include <aws/cal/hash.h> + +#ifndef AWS_BYO_CRYPTO +extern struct aws_hash *aws_sha256_default_new(struct aws_allocator *allocator); +extern struct aws_hash *aws_md5_default_new(struct aws_allocator *allocator); + +static aws_hash_new_fn *s_sha256_new_fn = aws_sha256_default_new; +static aws_hash_new_fn *s_md5_new_fn = aws_md5_default_new; +#else +static struct aws_hash *aws_hash_new_abort(struct aws_allocator *allocator) { + (void)allocator; + abort(); +} + +static aws_hash_new_fn *s_sha256_new_fn = aws_hash_new_abort; +static aws_hash_new_fn *s_md5_new_fn = aws_hash_new_abort; +#endif + +struct aws_hash *aws_sha256_new(struct aws_allocator *allocator) { + return s_sha256_new_fn(allocator); +} + +struct aws_hash *aws_md5_new(struct aws_allocator *allocator) { + return s_md5_new_fn(allocator); +} + +void aws_set_md5_new_fn(aws_hash_new_fn *fn) { + s_md5_new_fn = fn; +} + +void aws_set_sha256_new_fn(aws_hash_new_fn *fn) { + s_sha256_new_fn = fn; +} + +void aws_hash_destroy(struct aws_hash *hash) { + hash->vtable->destroy(hash); +} + +int aws_hash_update(struct aws_hash *hash, const struct aws_byte_cursor *to_hash) { + return hash->vtable->update(hash, to_hash); +} + +int aws_hash_finalize(struct aws_hash *hash, struct aws_byte_buf *output, size_t truncate_to) { + + if (truncate_to && truncate_to < hash->digest_size) { + size_t available_buffer = output->capacity - output->len; + if (available_buffer < truncate_to) { + return aws_raise_error(AWS_ERROR_SHORT_BUFFER); + } + + uint8_t tmp_output[128] = {0}; + AWS_ASSERT(sizeof(tmp_output) >= hash->digest_size); + + struct aws_byte_buf tmp_out_buf = aws_byte_buf_from_array(tmp_output, sizeof(tmp_output)); + tmp_out_buf.len = 0; + + if (hash->vtable->finalize(hash, &tmp_out_buf)) { + return AWS_OP_ERR; + } + + memcpy(output->buffer + output->len, tmp_output, truncate_to); + output->len += truncate_to; + return AWS_OP_SUCCESS; + } + + return hash->vtable->finalize(hash, output); +} + +static inline int compute_hash( + struct aws_hash *hash, + const struct aws_byte_cursor *input, + struct aws_byte_buf *output, + size_t truncate_to) { + if (!hash) { + return AWS_OP_ERR; + } + + if (aws_hash_update(hash, input)) { + aws_hash_destroy(hash); + return AWS_OP_ERR; + } + + if (aws_hash_finalize(hash, output, truncate_to)) { + aws_hash_destroy(hash); + return AWS_OP_ERR; + } + + aws_hash_destroy(hash); + return AWS_OP_SUCCESS; +} + +int aws_md5_compute( + struct aws_allocator *allocator, + const struct aws_byte_cursor *input, + struct aws_byte_buf *output, + size_t truncate_to) { + return compute_hash(aws_md5_new(allocator), input, output, truncate_to); +} + +int aws_sha256_compute( + struct aws_allocator *allocator, + const struct aws_byte_cursor *input, + struct aws_byte_buf *output, + size_t truncate_to) { + return compute_hash(aws_sha256_new(allocator), input, output, truncate_to); +} diff --git a/contrib/restricted/aws/aws-c-cal/source/hmac.c b/contrib/restricted/aws/aws-c-cal/source/hmac.c index 4664cbabdd..01f5ea5898 100644 --- a/contrib/restricted/aws/aws-c-cal/source/hmac.c +++ b/contrib/restricted/aws/aws-c-cal/source/hmac.c @@ -1,87 +1,87 @@ -/** - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0. - */ -#include <aws/cal/hmac.h> - -#ifndef AWS_BYO_CRYPTO -extern struct aws_hmac *aws_sha256_hmac_default_new( - struct aws_allocator *allocator, - const struct aws_byte_cursor *secret); -static aws_hmac_new_fn *s_sha256_hmac_new_fn = aws_sha256_hmac_default_new; -#else -static struct aws_hmac *aws_hmac_new_abort(struct aws_allocator *allocator, const struct aws_byte_cursor *secret) { - (void)allocator; - (void)secret; - abort(); -} - -static aws_hmac_new_fn *s_sha256_hmac_new_fn = aws_hmac_new_abort; -#endif - -struct aws_hmac *aws_sha256_hmac_new(struct aws_allocator *allocator, const struct aws_byte_cursor *secret) { - return s_sha256_hmac_new_fn(allocator, secret); -} - -void aws_set_sha256_hmac_new_fn(aws_hmac_new_fn *fn) { - s_sha256_hmac_new_fn = fn; -} - -void aws_hmac_destroy(struct aws_hmac *hmac) { - hmac->vtable->destroy(hmac); -} - -int aws_hmac_update(struct aws_hmac *hmac, const struct aws_byte_cursor *to_hmac) { - return hmac->vtable->update(hmac, to_hmac); -} - -int aws_hmac_finalize(struct aws_hmac *hmac, struct aws_byte_buf *output, size_t truncate_to) { - if (truncate_to && truncate_to < hmac->digest_size) { - size_t available_buffer = output->capacity - output->len; - if (available_buffer < truncate_to) { - return aws_raise_error(AWS_ERROR_SHORT_BUFFER); - } - - uint8_t tmp_output[128] = {0}; - AWS_ASSERT(sizeof(tmp_output) >= hmac->digest_size); - - struct aws_byte_buf tmp_out_buf = aws_byte_buf_from_array(tmp_output, sizeof(tmp_output)); - tmp_out_buf.len = 0; - - if (hmac->vtable->finalize(hmac, &tmp_out_buf)) { - return AWS_OP_ERR; - } - - memcpy(output->buffer + output->len, tmp_output, truncate_to); - output->len += truncate_to; - return AWS_OP_SUCCESS; - } - - return hmac->vtable->finalize(hmac, output); -} - -int aws_sha256_hmac_compute( - struct aws_allocator *allocator, - const struct aws_byte_cursor *secret, - const struct aws_byte_cursor *to_hmac, - struct aws_byte_buf *output, - size_t truncate_to) { - struct aws_hmac *hmac = aws_sha256_hmac_new(allocator, secret); - - if (!hmac) { - return AWS_OP_ERR; - } - - if (aws_hmac_update(hmac, to_hmac)) { - aws_hmac_destroy(hmac); - return AWS_OP_ERR; - } - - if (aws_hmac_finalize(hmac, output, truncate_to)) { - aws_hmac_destroy(hmac); - return AWS_OP_ERR; - } - - aws_hmac_destroy(hmac); - return AWS_OP_SUCCESS; -} +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ +#include <aws/cal/hmac.h> + +#ifndef AWS_BYO_CRYPTO +extern struct aws_hmac *aws_sha256_hmac_default_new( + struct aws_allocator *allocator, + const struct aws_byte_cursor *secret); +static aws_hmac_new_fn *s_sha256_hmac_new_fn = aws_sha256_hmac_default_new; +#else +static struct aws_hmac *aws_hmac_new_abort(struct aws_allocator *allocator, const struct aws_byte_cursor *secret) { + (void)allocator; + (void)secret; + abort(); +} + +static aws_hmac_new_fn *s_sha256_hmac_new_fn = aws_hmac_new_abort; +#endif + +struct aws_hmac *aws_sha256_hmac_new(struct aws_allocator *allocator, const struct aws_byte_cursor *secret) { + return s_sha256_hmac_new_fn(allocator, secret); +} + +void aws_set_sha256_hmac_new_fn(aws_hmac_new_fn *fn) { + s_sha256_hmac_new_fn = fn; +} + +void aws_hmac_destroy(struct aws_hmac *hmac) { + hmac->vtable->destroy(hmac); +} + +int aws_hmac_update(struct aws_hmac *hmac, const struct aws_byte_cursor *to_hmac) { + return hmac->vtable->update(hmac, to_hmac); +} + +int aws_hmac_finalize(struct aws_hmac *hmac, struct aws_byte_buf *output, size_t truncate_to) { + if (truncate_to && truncate_to < hmac->digest_size) { + size_t available_buffer = output->capacity - output->len; + if (available_buffer < truncate_to) { + return aws_raise_error(AWS_ERROR_SHORT_BUFFER); + } + + uint8_t tmp_output[128] = {0}; + AWS_ASSERT(sizeof(tmp_output) >= hmac->digest_size); + + struct aws_byte_buf tmp_out_buf = aws_byte_buf_from_array(tmp_output, sizeof(tmp_output)); + tmp_out_buf.len = 0; + + if (hmac->vtable->finalize(hmac, &tmp_out_buf)) { + return AWS_OP_ERR; + } + + memcpy(output->buffer + output->len, tmp_output, truncate_to); + output->len += truncate_to; + return AWS_OP_SUCCESS; + } + + return hmac->vtable->finalize(hmac, output); +} + +int aws_sha256_hmac_compute( + struct aws_allocator *allocator, + const struct aws_byte_cursor *secret, + const struct aws_byte_cursor *to_hmac, + struct aws_byte_buf *output, + size_t truncate_to) { + struct aws_hmac *hmac = aws_sha256_hmac_new(allocator, secret); + + if (!hmac) { + return AWS_OP_ERR; + } + + if (aws_hmac_update(hmac, to_hmac)) { + aws_hmac_destroy(hmac); + return AWS_OP_ERR; + } + + if (aws_hmac_finalize(hmac, output, truncate_to)) { + aws_hmac_destroy(hmac); + return AWS_OP_ERR; + } + + aws_hmac_destroy(hmac); + return AWS_OP_SUCCESS; +} diff --git a/contrib/restricted/aws/aws-c-cal/source/unix/openssl_platform_init.c b/contrib/restricted/aws/aws-c-cal/source/unix/openssl_platform_init.c index 83c94ed5aa..e98168b4ac 100644 --- a/contrib/restricted/aws/aws-c-cal/source/unix/openssl_platform_init.c +++ b/contrib/restricted/aws/aws-c-cal/source/unix/openssl_platform_init.c @@ -1,417 +1,417 @@ -/** - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0. - */ - -#include <aws/common/allocator.h> -#include <aws/common/mutex.h> -#include <aws/common/thread.h> - -#include <dlfcn.h> - -#include <aws/cal/private/opensslcrypto_common.h> - -#if defined(AWS_LIBCRYPTO_LOG_RESOLVE) -# define FLOGF(...) \ - do { \ - fprintf(stderr, "AWS libcrypto resolve: "); \ - fprintf(stderr, __VA_ARGS__); \ - fprintf(stderr, "\n"); \ - } while (0) -#else -# define FLOGF(...) -#endif - -static struct openssl_hmac_ctx_table hmac_ctx_table; -static struct openssl_evp_md_ctx_table evp_md_ctx_table; - -struct openssl_hmac_ctx_table *g_aws_openssl_hmac_ctx_table = NULL; -struct openssl_evp_md_ctx_table *g_aws_openssl_evp_md_ctx_table = NULL; - -/* weak refs to libcrypto functions to force them to at least try to link - * and avoid dead-stripping - */ -/* 1.1 */ -extern HMAC_CTX *HMAC_CTX_new(void) __attribute__((weak)) __attribute__((used)); -extern void HMAC_CTX_free(HMAC_CTX *) __attribute__((weak)) __attribute__((used)); -extern int HMAC_CTX_reset(HMAC_CTX *) __attribute__((weak)) __attribute__((used)); - -/* 1.0.2 */ -extern void HMAC_CTX_init(HMAC_CTX *) __attribute__((weak)) __attribute__((used)); -extern void HMAC_CTX_cleanup(HMAC_CTX *) __attribute__((weak)) __attribute__((used)); - -/* common */ -extern int HMAC_Update(HMAC_CTX *, const unsigned char *, size_t) __attribute__((weak)) __attribute__((used)); -extern int HMAC_Final(HMAC_CTX *, unsigned char *, unsigned int *) __attribute__((weak)) __attribute__((used)); -extern int HMAC_Init_ex(HMAC_CTX *, const void *, int, const EVP_MD *, ENGINE *) __attribute__((weak)) -__attribute__((used)); - -/* libcrypto 1.1 stub for init */ -static void s_hmac_ctx_init_noop(HMAC_CTX *ctx) { - (void)ctx; -} - -/* libcrypto 1.1 stub for clean_up */ -static void s_hmac_ctx_clean_up_noop(HMAC_CTX *ctx) { - (void)ctx; -} - -/* libcrypto 1.0 shim for new */ -static HMAC_CTX *s_hmac_ctx_new(void) { - AWS_PRECONDITION( - g_aws_openssl_hmac_ctx_table->init_fn != s_hmac_ctx_init_noop && - "libcrypto 1.0 init called on libcrypto 1.1 vtable"); - HMAC_CTX *ctx = aws_mem_calloc(aws_default_allocator(), 1, 300); - AWS_FATAL_ASSERT(ctx && "Unable to allocate to HMAC_CTX"); - g_aws_openssl_hmac_ctx_table->init_fn(ctx); - return ctx; -} - -/* libcrypto 1.0 shim for free */ -static void s_hmac_ctx_free(HMAC_CTX *ctx) { - AWS_PRECONDITION(ctx); - AWS_PRECONDITION( - g_aws_openssl_hmac_ctx_table->clean_up_fn != s_hmac_ctx_clean_up_noop && - "libcrypto 1.0 clean_up called on libcrypto 1.1 vtable"); - g_aws_openssl_hmac_ctx_table->clean_up_fn(ctx); - aws_mem_release(aws_default_allocator(), ctx); -} - -/* libcrypto 1.0 shim for reset, matches HMAC_CTX_reset semantics */ -static int s_hmac_ctx_reset(HMAC_CTX *ctx) { - AWS_PRECONDITION(ctx); - AWS_PRECONDITION( - g_aws_openssl_hmac_ctx_table->init_fn != s_hmac_ctx_init_noop && - g_aws_openssl_hmac_ctx_table->clean_up_fn != s_hmac_ctx_clean_up_noop && - "libcrypto 1.0 reset called on libcrypto 1.1 vtable"); - g_aws_openssl_hmac_ctx_table->clean_up_fn(ctx); - g_aws_openssl_hmac_ctx_table->init_fn(ctx); - return 1; -} - -static struct aws_mutex *s_libcrypto_locks = NULL; -static struct aws_allocator *s_libcrypto_allocator = NULL; - -static void s_locking_fn(int mode, int n, const char *unused0, int unused1) { - (void)unused0; - (void)unused1; - - if (mode & CRYPTO_LOCK) { - aws_mutex_lock(&s_libcrypto_locks[n]); - } else { - aws_mutex_unlock(&s_libcrypto_locks[n]); - } -} - -static unsigned long s_id_fn(void) { - return (unsigned long)aws_thread_current_thread_id(); -} - -enum aws_libcrypto_version { - AWS_LIBCRYPTO_NONE = 0, - AWS_LIBCRYPTO_1_0_2, - AWS_LIBCRYPTO_1_1_1, - AWS_LIBCRYPTO_LC, -} s_libcrypto_version = AWS_LIBCRYPTO_NONE; - -static int s_resolve_libcrypto_hmac(enum aws_libcrypto_version version, void *module) { - hmac_ctx_init init_fn = 0; - hmac_ctx_clean_up clean_up_fn = 0; - hmac_ctx_new new_fn = HMAC_CTX_new; - hmac_ctx_free free_fn = HMAC_CTX_free; - hmac_ctx_reset reset_fn = HMAC_CTX_reset; - hmac_ctx_update update_fn = HMAC_Update; - hmac_ctx_final final_fn = HMAC_Final; - hmac_ctx_init_ex init_ex_fn = HMAC_Init_ex; - - /* were symbols bound by static linking? */ - bool has_102_symbols = init_fn && clean_up_fn && update_fn && final_fn && init_ex_fn; - bool has_111_symbols = new_fn && free_fn && update_fn && final_fn && init_ex_fn && reset_fn; - - if (version == AWS_LIBCRYPTO_NONE) { - if (has_102_symbols) { - version = AWS_LIBCRYPTO_1_0_2; - FLOGF("auto-resolving libcrypto 1.0.2"); - } else if (has_111_symbols) { - version = AWS_LIBCRYPTO_1_1_1; - FLOGF("auto-resolving libcrypto 1.1.1"); - } else { - /* not pre-linked, need to ask for a specific version */ - return AWS_LIBCRYPTO_NONE; - } - } - - if (has_102_symbols) { - FLOGF("found static libcrypto 1.0.2 HMAC"); - } - if (has_111_symbols) { - FLOGF("found static libcrypto 1.1.1 HMAC"); - } - - /* If symbols aren't already found, try to find the requested version */ - /* when built as a shared lib, and multiple versions of openssl are possibly - * available (e.g. brazil), select 1.0.2 by default for consistency */ - if (!has_102_symbols && version == AWS_LIBCRYPTO_1_0_2) { - *(void **)(&init_fn) = dlsym(module, "HMAC_CTX_init"); - *(void **)(&clean_up_fn) = dlsym(module, "HMAC_CTX_cleanup"); - *(void **)(&update_fn) = dlsym(module, "HMAC_Update"); - *(void **)(&final_fn) = dlsym(module, "HMAC_Final"); - *(void **)(&init_ex_fn) = dlsym(module, "HMAC_Init_ex"); - if (init_fn) { - FLOGF("found dynamic libcrypto 1.0.2 HMAC symbols"); - } - } - - if (!has_111_symbols && version == AWS_LIBCRYPTO_1_1_1) { - *(void **)(&new_fn) = dlsym(module, "HMAC_CTX_new"); - *(void **)(&reset_fn) = dlsym(module, "HMAC_CTX_reset"); - *(void **)(&free_fn) = dlsym(module, "HMAC_CTX_free"); - *(void **)(&update_fn) = dlsym(module, "HMAC_Update"); - *(void **)(&final_fn) = dlsym(module, "HMAC_Final"); - *(void **)(&init_ex_fn) = dlsym(module, "HMAC_Init_ex"); - if (new_fn) { - FLOGF("found dynamic libcrypto 1.1.1 HMAC symbols"); - } - } - - /* Fill out the vtable for the requested version */ - if (version == AWS_LIBCRYPTO_1_0_2 && init_fn) { - hmac_ctx_table.new_fn = s_hmac_ctx_new; - hmac_ctx_table.reset_fn = s_hmac_ctx_reset; - hmac_ctx_table.free_fn = s_hmac_ctx_free; - hmac_ctx_table.init_fn = init_fn; - hmac_ctx_table.clean_up_fn = clean_up_fn; - } else if (version == AWS_LIBCRYPTO_1_1_1 && new_fn) { - hmac_ctx_table.new_fn = new_fn; - hmac_ctx_table.reset_fn = reset_fn; - hmac_ctx_table.free_fn = free_fn; - hmac_ctx_table.init_fn = s_hmac_ctx_init_noop; - hmac_ctx_table.clean_up_fn = s_hmac_ctx_clean_up_noop; - } - hmac_ctx_table.update_fn = update_fn; - hmac_ctx_table.final_fn = final_fn; - hmac_ctx_table.init_ex_fn = init_ex_fn; - g_aws_openssl_hmac_ctx_table = &hmac_ctx_table; - - return version; -} - -/* EVP_MD_CTX API */ -/* 1.0.2 NOTE: these are macros in 1.1.x, so we have to undef them to weak link */ -#if defined(EVP_MD_CTX_create) -# pragma push_macro("EVP_MD_CTX_create") -# undef EVP_MD_CTX_create -#endif -extern EVP_MD_CTX *EVP_MD_CTX_create(void) __attribute__((weak, used)); -static evp_md_ctx_new s_EVP_MD_CTX_create = 0; -#if defined(EVP_MD_CTX_create) -# pragma pop_macro("EVP_MD_CTX_create") -#endif - -#if defined(EVP_MD_CTX_destroy) -# pragma push_macro("EVP_MD_CTX_destroy") -# undef EVP_MD_CTX_destroy -#endif -extern void EVP_MD_CTX_destroy(EVP_MD_CTX *) __attribute__((weak, used)); -static evp_md_ctx_free s_EVP_MD_CTX_destroy = 0; -#if defined(EVP_MD_CTX_destroy) -# pragma pop_macro("EVP_MD_CTX_destroy") -#endif - -/* 1.1 */ -extern EVP_MD_CTX *EVP_MD_CTX_new(void) __attribute__((weak, used)); -extern void EVP_MD_CTX_free(EVP_MD_CTX *) __attribute__((weak, used)); - -/* common */ -extern int EVP_DigestInit_ex(EVP_MD_CTX *, const EVP_MD *, ENGINE *) __attribute__((weak, used)); -extern int EVP_DigestUpdate(EVP_MD_CTX *, const void *, size_t) __attribute__((weak, used)); -extern int EVP_DigestFinal_ex(EVP_MD_CTX *, unsigned char *, unsigned int *) __attribute__((weak, used)); - -static int s_resolve_libcrypto_md(enum aws_libcrypto_version version, void *module) { - /* OpenSSL changed the EVP api in 1.1 to use new/free verbs */ - evp_md_ctx_new md_new_fn = EVP_MD_CTX_new; - evp_md_ctx_new md_create_fn = s_EVP_MD_CTX_create; - evp_md_ctx_free md_free_fn = EVP_MD_CTX_free; - evp_md_ctx_free md_destroy_fn = s_EVP_MD_CTX_destroy; - evp_md_ctx_digest_init_ex md_init_ex_fn = EVP_DigestInit_ex; - evp_md_ctx_digest_update md_update_fn = EVP_DigestUpdate; - evp_md_ctx_digest_final_ex md_final_ex_fn = EVP_DigestFinal_ex; - - bool has_102_symbols = md_create_fn && md_destroy_fn && md_init_ex_fn && md_update_fn && md_final_ex_fn; - bool has_111_symbols = md_new_fn && md_free_fn && md_init_ex_fn && md_update_fn && md_final_ex_fn; - - if (has_102_symbols) { - FLOGF("found static libcrypto 1.0.2 EVP_MD"); - } - if (has_111_symbols) { - FLOGF("found static libcrypto 1.1.1 EVP_MD"); - } - - if (!has_102_symbols && version == AWS_LIBCRYPTO_1_0_2) { - *(void **)(&md_create_fn) = dlsym(module, "EVP_MD_CTX_create"); - *(void **)(&md_destroy_fn) = dlsym(module, "EVP_MD_CTX_destroy"); - *(void **)(&md_init_ex_fn) = dlsym(module, "EVP_DigestInit_ex"); - *(void **)(&md_update_fn) = dlsym(module, "EVP_DigestUpdate"); - *(void **)(&md_final_ex_fn) = dlsym(module, "EVP_DigestFinal_ex"); - if (md_create_fn) { - FLOGF("found dynamic libcrypto 1.0.2 EVP_MD symbols"); - } - } - - if (!has_111_symbols && version == AWS_LIBCRYPTO_1_1_1) { - *(void **)(&md_new_fn) = dlsym(module, "EVP_MD_CTX_new"); - *(void **)(&md_free_fn) = dlsym(module, "EVP_MD_CTX_free"); - *(void **)(&md_init_ex_fn) = dlsym(module, "EVP_DigestInit_ex"); - *(void **)(&md_update_fn) = dlsym(module, "EVP_DigestUpdate"); - *(void **)(&md_final_ex_fn) = dlsym(module, "EVP_DigestFinal_ex"); - if (md_new_fn) { - FLOGF("found dynamic libcrypto 1.1.1 EVP_MD symbols"); - } - } - - /* Add the found symbols to the vtable */ - if (version == AWS_LIBCRYPTO_1_0_2 && md_create_fn) { - evp_md_ctx_table.new_fn = md_create_fn; - evp_md_ctx_table.free_fn = md_destroy_fn; - evp_md_ctx_table.init_ex_fn = md_init_ex_fn; - evp_md_ctx_table.update_fn = md_update_fn; - evp_md_ctx_table.final_ex_fn = md_final_ex_fn; - g_aws_openssl_evp_md_ctx_table = &evp_md_ctx_table; - return version; - } else if (version == AWS_LIBCRYPTO_1_1_1 && md_new_fn) { - evp_md_ctx_table.new_fn = md_new_fn; - evp_md_ctx_table.free_fn = md_free_fn; - evp_md_ctx_table.init_ex_fn = md_init_ex_fn; - evp_md_ctx_table.update_fn = md_update_fn; - evp_md_ctx_table.final_ex_fn = md_final_ex_fn; - g_aws_openssl_evp_md_ctx_table = &evp_md_ctx_table; - return version; - } - - return AWS_LIBCRYPTO_NONE; -} - -static int s_resolve_libcrypto_symbols(enum aws_libcrypto_version version, void *module) { - int found_version = s_resolve_libcrypto_hmac(version, module); - if (!found_version) { - return AWS_LIBCRYPTO_NONE; - } - if (!s_resolve_libcrypto_md(found_version, module)) { - return AWS_LIBCRYPTO_NONE; - } - return found_version; -} - -static int s_resolve_libcrypto_version(enum aws_libcrypto_version version) { - const char *libcrypto_102 = "libcrypto.so.1.0.0"; - const char *libcrypto_111 = "libcrypto.so.1.1"; - switch (version) { - case AWS_LIBCRYPTO_NONE: { - FLOGF("searching process and loaded modules"); - void *process = dlopen(NULL, RTLD_NOW); - AWS_FATAL_ASSERT(process && "Unable to load symbols from process space"); - int result = s_resolve_libcrypto_symbols(version, process); - dlclose(process); - return result; - } - case AWS_LIBCRYPTO_1_0_2: { - FLOGF("loading libcrypto 1.0.2"); - void *module = dlopen(libcrypto_102, RTLD_NOW); - if (module) { - FLOGF("resolving against libcrypto 1.0.2"); - int result = s_resolve_libcrypto_symbols(version, module); - dlclose(module); - return result; - } - FLOGF("libcrypto 1.0.2 not found"); - break; - } - case AWS_LIBCRYPTO_1_1_1: { - FLOGF("loading libcrypto 1.1.1"); - void *module = dlopen(libcrypto_111, RTLD_NOW); - if (module) { - FLOGF("resolving against libcrypto 1.1.1"); - int result = s_resolve_libcrypto_symbols(version, module); - dlclose(module); - return result; - } - FLOGF("libcrypto 1.1.1 not found"); - break; - } - default: - AWS_FATAL_ASSERT("Attempted to use an unsupported version of libcrypto"); - } - return AWS_LIBCRYPTO_NONE; -} - -static int s_resolve_libcrypto(void) { - if (s_libcrypto_version != AWS_LIBCRYPTO_NONE) { - return s_libcrypto_version; - } - - /* Try to auto-resolve against what's linked in/process space */ - FLOGF("Attempting auto-resolve against static linkage"); - s_libcrypto_version = s_resolve_libcrypto_version(AWS_LIBCRYPTO_NONE); - /* try 1.0.2 */ - if (s_libcrypto_version == AWS_LIBCRYPTO_NONE) { - FLOGF("Attempting resolve against libcrypto 1.0.2"); - s_libcrypto_version = s_resolve_libcrypto_version(AWS_LIBCRYPTO_1_0_2); - } - /* try 1.1.1 */ - if (s_libcrypto_version == AWS_LIBCRYPTO_NONE) { - FLOGF("Attempting resolve against libcrypto 1.1.1"); - s_libcrypto_version = s_resolve_libcrypto_version(AWS_LIBCRYPTO_1_1_1); - } - - return s_libcrypto_version; -} - -/* Ignore warnings about how CRYPTO_get_locking_callback() always returns NULL on 1.1.1 */ -#if !defined(__GNUC__) || (__GNUC__ >= 4 && __GNUC_MINOR__ > 1) -# pragma GCC diagnostic push -# pragma GCC diagnostic ignored "-Waddress" -#endif - -void aws_cal_platform_init(struct aws_allocator *allocator) { - s_libcrypto_allocator = allocator; - - int version = s_resolve_libcrypto(); - AWS_FATAL_ASSERT(version != AWS_LIBCRYPTO_NONE && "libcrypto could not be resolved"); - - /* Ensure that libcrypto 1.0.2 has working locking mechanisms. This code is macro'ed - * by libcrypto to be a no-op on 1.1.1 */ - if (!CRYPTO_get_locking_callback()) { - /* on 1.1.1 this is a no-op */ - CRYPTO_set_locking_callback(s_locking_fn); - if (CRYPTO_get_locking_callback() == s_locking_fn) { - s_libcrypto_locks = aws_mem_acquire(allocator, sizeof(struct aws_mutex) * CRYPTO_num_locks()); - AWS_FATAL_ASSERT(s_libcrypto_locks); - size_t lock_count = (size_t)CRYPTO_num_locks(); - for (size_t i = 0; i < lock_count; ++i) { - aws_mutex_init(&s_libcrypto_locks[i]); - } - } - } - - if (!CRYPTO_get_id_callback()) { - CRYPTO_set_id_callback(s_id_fn); - } -} - -void aws_cal_platform_clean_up(void) { - if (CRYPTO_get_locking_callback() == s_locking_fn) { - CRYPTO_set_locking_callback(NULL); - size_t lock_count = (size_t)CRYPTO_num_locks(); - for (size_t i = 0; i < lock_count; ++i) { - aws_mutex_clean_up(&s_libcrypto_locks[i]); - } - aws_mem_release(s_libcrypto_allocator, s_libcrypto_locks); - } - - if (CRYPTO_get_id_callback() == s_id_fn) { - CRYPTO_set_id_callback(NULL); - } -} -#if !defined(__GNUC__) || (__GNUC__ >= 4 && __GNUC_MINOR__ > 1) -# pragma GCC diagnostic pop -#endif +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ + +#include <aws/common/allocator.h> +#include <aws/common/mutex.h> +#include <aws/common/thread.h> + +#include <dlfcn.h> + +#include <aws/cal/private/opensslcrypto_common.h> + +#if defined(AWS_LIBCRYPTO_LOG_RESOLVE) +# define FLOGF(...) \ + do { \ + fprintf(stderr, "AWS libcrypto resolve: "); \ + fprintf(stderr, __VA_ARGS__); \ + fprintf(stderr, "\n"); \ + } while (0) +#else +# define FLOGF(...) +#endif + +static struct openssl_hmac_ctx_table hmac_ctx_table; +static struct openssl_evp_md_ctx_table evp_md_ctx_table; + +struct openssl_hmac_ctx_table *g_aws_openssl_hmac_ctx_table = NULL; +struct openssl_evp_md_ctx_table *g_aws_openssl_evp_md_ctx_table = NULL; + +/* weak refs to libcrypto functions to force them to at least try to link + * and avoid dead-stripping + */ +/* 1.1 */ +extern HMAC_CTX *HMAC_CTX_new(void) __attribute__((weak)) __attribute__((used)); +extern void HMAC_CTX_free(HMAC_CTX *) __attribute__((weak)) __attribute__((used)); +extern int HMAC_CTX_reset(HMAC_CTX *) __attribute__((weak)) __attribute__((used)); + +/* 1.0.2 */ +extern void HMAC_CTX_init(HMAC_CTX *) __attribute__((weak)) __attribute__((used)); +extern void HMAC_CTX_cleanup(HMAC_CTX *) __attribute__((weak)) __attribute__((used)); + +/* common */ +extern int HMAC_Update(HMAC_CTX *, const unsigned char *, size_t) __attribute__((weak)) __attribute__((used)); +extern int HMAC_Final(HMAC_CTX *, unsigned char *, unsigned int *) __attribute__((weak)) __attribute__((used)); +extern int HMAC_Init_ex(HMAC_CTX *, const void *, int, const EVP_MD *, ENGINE *) __attribute__((weak)) +__attribute__((used)); + +/* libcrypto 1.1 stub for init */ +static void s_hmac_ctx_init_noop(HMAC_CTX *ctx) { + (void)ctx; +} + +/* libcrypto 1.1 stub for clean_up */ +static void s_hmac_ctx_clean_up_noop(HMAC_CTX *ctx) { + (void)ctx; +} + +/* libcrypto 1.0 shim for new */ +static HMAC_CTX *s_hmac_ctx_new(void) { + AWS_PRECONDITION( + g_aws_openssl_hmac_ctx_table->init_fn != s_hmac_ctx_init_noop && + "libcrypto 1.0 init called on libcrypto 1.1 vtable"); + HMAC_CTX *ctx = aws_mem_calloc(aws_default_allocator(), 1, 300); + AWS_FATAL_ASSERT(ctx && "Unable to allocate to HMAC_CTX"); + g_aws_openssl_hmac_ctx_table->init_fn(ctx); + return ctx; +} + +/* libcrypto 1.0 shim for free */ +static void s_hmac_ctx_free(HMAC_CTX *ctx) { + AWS_PRECONDITION(ctx); + AWS_PRECONDITION( + g_aws_openssl_hmac_ctx_table->clean_up_fn != s_hmac_ctx_clean_up_noop && + "libcrypto 1.0 clean_up called on libcrypto 1.1 vtable"); + g_aws_openssl_hmac_ctx_table->clean_up_fn(ctx); + aws_mem_release(aws_default_allocator(), ctx); +} + +/* libcrypto 1.0 shim for reset, matches HMAC_CTX_reset semantics */ +static int s_hmac_ctx_reset(HMAC_CTX *ctx) { + AWS_PRECONDITION(ctx); + AWS_PRECONDITION( + g_aws_openssl_hmac_ctx_table->init_fn != s_hmac_ctx_init_noop && + g_aws_openssl_hmac_ctx_table->clean_up_fn != s_hmac_ctx_clean_up_noop && + "libcrypto 1.0 reset called on libcrypto 1.1 vtable"); + g_aws_openssl_hmac_ctx_table->clean_up_fn(ctx); + g_aws_openssl_hmac_ctx_table->init_fn(ctx); + return 1; +} + +static struct aws_mutex *s_libcrypto_locks = NULL; +static struct aws_allocator *s_libcrypto_allocator = NULL; + +static void s_locking_fn(int mode, int n, const char *unused0, int unused1) { + (void)unused0; + (void)unused1; + + if (mode & CRYPTO_LOCK) { + aws_mutex_lock(&s_libcrypto_locks[n]); + } else { + aws_mutex_unlock(&s_libcrypto_locks[n]); + } +} + +static unsigned long s_id_fn(void) { + return (unsigned long)aws_thread_current_thread_id(); +} + +enum aws_libcrypto_version { + AWS_LIBCRYPTO_NONE = 0, + AWS_LIBCRYPTO_1_0_2, + AWS_LIBCRYPTO_1_1_1, + AWS_LIBCRYPTO_LC, +} s_libcrypto_version = AWS_LIBCRYPTO_NONE; + +static int s_resolve_libcrypto_hmac(enum aws_libcrypto_version version, void *module) { + hmac_ctx_init init_fn = 0; + hmac_ctx_clean_up clean_up_fn = 0; + hmac_ctx_new new_fn = HMAC_CTX_new; + hmac_ctx_free free_fn = HMAC_CTX_free; + hmac_ctx_reset reset_fn = HMAC_CTX_reset; + hmac_ctx_update update_fn = HMAC_Update; + hmac_ctx_final final_fn = HMAC_Final; + hmac_ctx_init_ex init_ex_fn = HMAC_Init_ex; + + /* were symbols bound by static linking? */ + bool has_102_symbols = init_fn && clean_up_fn && update_fn && final_fn && init_ex_fn; + bool has_111_symbols = new_fn && free_fn && update_fn && final_fn && init_ex_fn && reset_fn; + + if (version == AWS_LIBCRYPTO_NONE) { + if (has_102_symbols) { + version = AWS_LIBCRYPTO_1_0_2; + FLOGF("auto-resolving libcrypto 1.0.2"); + } else if (has_111_symbols) { + version = AWS_LIBCRYPTO_1_1_1; + FLOGF("auto-resolving libcrypto 1.1.1"); + } else { + /* not pre-linked, need to ask for a specific version */ + return AWS_LIBCRYPTO_NONE; + } + } + + if (has_102_symbols) { + FLOGF("found static libcrypto 1.0.2 HMAC"); + } + if (has_111_symbols) { + FLOGF("found static libcrypto 1.1.1 HMAC"); + } + + /* If symbols aren't already found, try to find the requested version */ + /* when built as a shared lib, and multiple versions of openssl are possibly + * available (e.g. brazil), select 1.0.2 by default for consistency */ + if (!has_102_symbols && version == AWS_LIBCRYPTO_1_0_2) { + *(void **)(&init_fn) = dlsym(module, "HMAC_CTX_init"); + *(void **)(&clean_up_fn) = dlsym(module, "HMAC_CTX_cleanup"); + *(void **)(&update_fn) = dlsym(module, "HMAC_Update"); + *(void **)(&final_fn) = dlsym(module, "HMAC_Final"); + *(void **)(&init_ex_fn) = dlsym(module, "HMAC_Init_ex"); + if (init_fn) { + FLOGF("found dynamic libcrypto 1.0.2 HMAC symbols"); + } + } + + if (!has_111_symbols && version == AWS_LIBCRYPTO_1_1_1) { + *(void **)(&new_fn) = dlsym(module, "HMAC_CTX_new"); + *(void **)(&reset_fn) = dlsym(module, "HMAC_CTX_reset"); + *(void **)(&free_fn) = dlsym(module, "HMAC_CTX_free"); + *(void **)(&update_fn) = dlsym(module, "HMAC_Update"); + *(void **)(&final_fn) = dlsym(module, "HMAC_Final"); + *(void **)(&init_ex_fn) = dlsym(module, "HMAC_Init_ex"); + if (new_fn) { + FLOGF("found dynamic libcrypto 1.1.1 HMAC symbols"); + } + } + + /* Fill out the vtable for the requested version */ + if (version == AWS_LIBCRYPTO_1_0_2 && init_fn) { + hmac_ctx_table.new_fn = s_hmac_ctx_new; + hmac_ctx_table.reset_fn = s_hmac_ctx_reset; + hmac_ctx_table.free_fn = s_hmac_ctx_free; + hmac_ctx_table.init_fn = init_fn; + hmac_ctx_table.clean_up_fn = clean_up_fn; + } else if (version == AWS_LIBCRYPTO_1_1_1 && new_fn) { + hmac_ctx_table.new_fn = new_fn; + hmac_ctx_table.reset_fn = reset_fn; + hmac_ctx_table.free_fn = free_fn; + hmac_ctx_table.init_fn = s_hmac_ctx_init_noop; + hmac_ctx_table.clean_up_fn = s_hmac_ctx_clean_up_noop; + } + hmac_ctx_table.update_fn = update_fn; + hmac_ctx_table.final_fn = final_fn; + hmac_ctx_table.init_ex_fn = init_ex_fn; + g_aws_openssl_hmac_ctx_table = &hmac_ctx_table; + + return version; +} + +/* EVP_MD_CTX API */ +/* 1.0.2 NOTE: these are macros in 1.1.x, so we have to undef them to weak link */ +#if defined(EVP_MD_CTX_create) +# pragma push_macro("EVP_MD_CTX_create") +# undef EVP_MD_CTX_create +#endif +extern EVP_MD_CTX *EVP_MD_CTX_create(void) __attribute__((weak, used)); +static evp_md_ctx_new s_EVP_MD_CTX_create = 0; +#if defined(EVP_MD_CTX_create) +# pragma pop_macro("EVP_MD_CTX_create") +#endif + +#if defined(EVP_MD_CTX_destroy) +# pragma push_macro("EVP_MD_CTX_destroy") +# undef EVP_MD_CTX_destroy +#endif +extern void EVP_MD_CTX_destroy(EVP_MD_CTX *) __attribute__((weak, used)); +static evp_md_ctx_free s_EVP_MD_CTX_destroy = 0; +#if defined(EVP_MD_CTX_destroy) +# pragma pop_macro("EVP_MD_CTX_destroy") +#endif + +/* 1.1 */ +extern EVP_MD_CTX *EVP_MD_CTX_new(void) __attribute__((weak, used)); +extern void EVP_MD_CTX_free(EVP_MD_CTX *) __attribute__((weak, used)); + +/* common */ +extern int EVP_DigestInit_ex(EVP_MD_CTX *, const EVP_MD *, ENGINE *) __attribute__((weak, used)); +extern int EVP_DigestUpdate(EVP_MD_CTX *, const void *, size_t) __attribute__((weak, used)); +extern int EVP_DigestFinal_ex(EVP_MD_CTX *, unsigned char *, unsigned int *) __attribute__((weak, used)); + +static int s_resolve_libcrypto_md(enum aws_libcrypto_version version, void *module) { + /* OpenSSL changed the EVP api in 1.1 to use new/free verbs */ + evp_md_ctx_new md_new_fn = EVP_MD_CTX_new; + evp_md_ctx_new md_create_fn = s_EVP_MD_CTX_create; + evp_md_ctx_free md_free_fn = EVP_MD_CTX_free; + evp_md_ctx_free md_destroy_fn = s_EVP_MD_CTX_destroy; + evp_md_ctx_digest_init_ex md_init_ex_fn = EVP_DigestInit_ex; + evp_md_ctx_digest_update md_update_fn = EVP_DigestUpdate; + evp_md_ctx_digest_final_ex md_final_ex_fn = EVP_DigestFinal_ex; + + bool has_102_symbols = md_create_fn && md_destroy_fn && md_init_ex_fn && md_update_fn && md_final_ex_fn; + bool has_111_symbols = md_new_fn && md_free_fn && md_init_ex_fn && md_update_fn && md_final_ex_fn; + + if (has_102_symbols) { + FLOGF("found static libcrypto 1.0.2 EVP_MD"); + } + if (has_111_symbols) { + FLOGF("found static libcrypto 1.1.1 EVP_MD"); + } + + if (!has_102_symbols && version == AWS_LIBCRYPTO_1_0_2) { + *(void **)(&md_create_fn) = dlsym(module, "EVP_MD_CTX_create"); + *(void **)(&md_destroy_fn) = dlsym(module, "EVP_MD_CTX_destroy"); + *(void **)(&md_init_ex_fn) = dlsym(module, "EVP_DigestInit_ex"); + *(void **)(&md_update_fn) = dlsym(module, "EVP_DigestUpdate"); + *(void **)(&md_final_ex_fn) = dlsym(module, "EVP_DigestFinal_ex"); + if (md_create_fn) { + FLOGF("found dynamic libcrypto 1.0.2 EVP_MD symbols"); + } + } + + if (!has_111_symbols && version == AWS_LIBCRYPTO_1_1_1) { + *(void **)(&md_new_fn) = dlsym(module, "EVP_MD_CTX_new"); + *(void **)(&md_free_fn) = dlsym(module, "EVP_MD_CTX_free"); + *(void **)(&md_init_ex_fn) = dlsym(module, "EVP_DigestInit_ex"); + *(void **)(&md_update_fn) = dlsym(module, "EVP_DigestUpdate"); + *(void **)(&md_final_ex_fn) = dlsym(module, "EVP_DigestFinal_ex"); + if (md_new_fn) { + FLOGF("found dynamic libcrypto 1.1.1 EVP_MD symbols"); + } + } + + /* Add the found symbols to the vtable */ + if (version == AWS_LIBCRYPTO_1_0_2 && md_create_fn) { + evp_md_ctx_table.new_fn = md_create_fn; + evp_md_ctx_table.free_fn = md_destroy_fn; + evp_md_ctx_table.init_ex_fn = md_init_ex_fn; + evp_md_ctx_table.update_fn = md_update_fn; + evp_md_ctx_table.final_ex_fn = md_final_ex_fn; + g_aws_openssl_evp_md_ctx_table = &evp_md_ctx_table; + return version; + } else if (version == AWS_LIBCRYPTO_1_1_1 && md_new_fn) { + evp_md_ctx_table.new_fn = md_new_fn; + evp_md_ctx_table.free_fn = md_free_fn; + evp_md_ctx_table.init_ex_fn = md_init_ex_fn; + evp_md_ctx_table.update_fn = md_update_fn; + evp_md_ctx_table.final_ex_fn = md_final_ex_fn; + g_aws_openssl_evp_md_ctx_table = &evp_md_ctx_table; + return version; + } + + return AWS_LIBCRYPTO_NONE; +} + +static int s_resolve_libcrypto_symbols(enum aws_libcrypto_version version, void *module) { + int found_version = s_resolve_libcrypto_hmac(version, module); + if (!found_version) { + return AWS_LIBCRYPTO_NONE; + } + if (!s_resolve_libcrypto_md(found_version, module)) { + return AWS_LIBCRYPTO_NONE; + } + return found_version; +} + +static int s_resolve_libcrypto_version(enum aws_libcrypto_version version) { + const char *libcrypto_102 = "libcrypto.so.1.0.0"; + const char *libcrypto_111 = "libcrypto.so.1.1"; + switch (version) { + case AWS_LIBCRYPTO_NONE: { + FLOGF("searching process and loaded modules"); + void *process = dlopen(NULL, RTLD_NOW); + AWS_FATAL_ASSERT(process && "Unable to load symbols from process space"); + int result = s_resolve_libcrypto_symbols(version, process); + dlclose(process); + return result; + } + case AWS_LIBCRYPTO_1_0_2: { + FLOGF("loading libcrypto 1.0.2"); + void *module = dlopen(libcrypto_102, RTLD_NOW); + if (module) { + FLOGF("resolving against libcrypto 1.0.2"); + int result = s_resolve_libcrypto_symbols(version, module); + dlclose(module); + return result; + } + FLOGF("libcrypto 1.0.2 not found"); + break; + } + case AWS_LIBCRYPTO_1_1_1: { + FLOGF("loading libcrypto 1.1.1"); + void *module = dlopen(libcrypto_111, RTLD_NOW); + if (module) { + FLOGF("resolving against libcrypto 1.1.1"); + int result = s_resolve_libcrypto_symbols(version, module); + dlclose(module); + return result; + } + FLOGF("libcrypto 1.1.1 not found"); + break; + } + default: + AWS_FATAL_ASSERT("Attempted to use an unsupported version of libcrypto"); + } + return AWS_LIBCRYPTO_NONE; +} + +static int s_resolve_libcrypto(void) { + if (s_libcrypto_version != AWS_LIBCRYPTO_NONE) { + return s_libcrypto_version; + } + + /* Try to auto-resolve against what's linked in/process space */ + FLOGF("Attempting auto-resolve against static linkage"); + s_libcrypto_version = s_resolve_libcrypto_version(AWS_LIBCRYPTO_NONE); + /* try 1.0.2 */ + if (s_libcrypto_version == AWS_LIBCRYPTO_NONE) { + FLOGF("Attempting resolve against libcrypto 1.0.2"); + s_libcrypto_version = s_resolve_libcrypto_version(AWS_LIBCRYPTO_1_0_2); + } + /* try 1.1.1 */ + if (s_libcrypto_version == AWS_LIBCRYPTO_NONE) { + FLOGF("Attempting resolve against libcrypto 1.1.1"); + s_libcrypto_version = s_resolve_libcrypto_version(AWS_LIBCRYPTO_1_1_1); + } + + return s_libcrypto_version; +} + +/* Ignore warnings about how CRYPTO_get_locking_callback() always returns NULL on 1.1.1 */ +#if !defined(__GNUC__) || (__GNUC__ >= 4 && __GNUC_MINOR__ > 1) +# pragma GCC diagnostic push +# pragma GCC diagnostic ignored "-Waddress" +#endif + +void aws_cal_platform_init(struct aws_allocator *allocator) { + s_libcrypto_allocator = allocator; + + int version = s_resolve_libcrypto(); + AWS_FATAL_ASSERT(version != AWS_LIBCRYPTO_NONE && "libcrypto could not be resolved"); + + /* Ensure that libcrypto 1.0.2 has working locking mechanisms. This code is macro'ed + * by libcrypto to be a no-op on 1.1.1 */ + if (!CRYPTO_get_locking_callback()) { + /* on 1.1.1 this is a no-op */ + CRYPTO_set_locking_callback(s_locking_fn); + if (CRYPTO_get_locking_callback() == s_locking_fn) { + s_libcrypto_locks = aws_mem_acquire(allocator, sizeof(struct aws_mutex) * CRYPTO_num_locks()); + AWS_FATAL_ASSERT(s_libcrypto_locks); + size_t lock_count = (size_t)CRYPTO_num_locks(); + for (size_t i = 0; i < lock_count; ++i) { + aws_mutex_init(&s_libcrypto_locks[i]); + } + } + } + + if (!CRYPTO_get_id_callback()) { + CRYPTO_set_id_callback(s_id_fn); + } +} + +void aws_cal_platform_clean_up(void) { + if (CRYPTO_get_locking_callback() == s_locking_fn) { + CRYPTO_set_locking_callback(NULL); + size_t lock_count = (size_t)CRYPTO_num_locks(); + for (size_t i = 0; i < lock_count; ++i) { + aws_mutex_clean_up(&s_libcrypto_locks[i]); + } + aws_mem_release(s_libcrypto_allocator, s_libcrypto_locks); + } + + if (CRYPTO_get_id_callback() == s_id_fn) { + CRYPTO_set_id_callback(NULL); + } +} +#if !defined(__GNUC__) || (__GNUC__ >= 4 && __GNUC_MINOR__ > 1) +# pragma GCC diagnostic pop +#endif diff --git a/contrib/restricted/aws/aws-c-cal/source/unix/opensslcrypto_ecc.c b/contrib/restricted/aws/aws-c-cal/source/unix/opensslcrypto_ecc.c index 153bcd5f4e..14be8c3df5 100644 --- a/contrib/restricted/aws/aws-c-cal/source/unix/opensslcrypto_ecc.c +++ b/contrib/restricted/aws/aws-c-cal/source/unix/opensslcrypto_ecc.c @@ -1,374 +1,374 @@ -/** - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0. - */ -#include <aws/cal/private/ecc.h> - -#include <aws/cal/cal.h> -#include <aws/cal/private/der.h> - -#include <openssl/bn.h> -#include <openssl/ec.h> -#include <openssl/ecdsa.h> -#include <openssl/obj_mac.h> - -struct libcrypto_ecc_key { - struct aws_ecc_key_pair key_pair; - EC_KEY *ec_key; -}; - -static int s_curve_name_to_nid(enum aws_ecc_curve_name curve_name) { - switch (curve_name) { - case AWS_CAL_ECDSA_P256: - return NID_X9_62_prime256v1; - case AWS_CAL_ECDSA_P384: - return NID_secp384r1; - } - - AWS_FATAL_ASSERT(!"Unsupported elliptic curve name"); - return -1; -} - -static void s_key_pair_destroy(struct aws_ecc_key_pair *key_pair) { - - if (key_pair) { - aws_byte_buf_clean_up(&key_pair->pub_x); - aws_byte_buf_clean_up(&key_pair->pub_y); - aws_byte_buf_clean_up_secure(&key_pair->priv_d); - - struct libcrypto_ecc_key *key_impl = key_pair->impl; - - if (key_impl->ec_key) { - EC_KEY_free(key_impl->ec_key); - } - aws_mem_release(key_pair->allocator, key_pair); - } -} - -static int s_sign_payload( - const struct aws_ecc_key_pair *key_pair, - const struct aws_byte_cursor *hash, - struct aws_byte_buf *signature_output) { - struct libcrypto_ecc_key *libcrypto_key_pair = key_pair->impl; - - unsigned int signature_size = signature_output->capacity - signature_output->len; - int ret_val = ECDSA_sign( - 0, - hash->ptr, - hash->len, - signature_output->buffer + signature_output->len, - &signature_size, - libcrypto_key_pair->ec_key); - signature_output->len += signature_size; - - return ret_val == 1 ? AWS_OP_SUCCESS : aws_raise_error(AWS_ERROR_INVALID_ARGUMENT); -} - -static int s_verify_payload( - const struct aws_ecc_key_pair *key_pair, - const struct aws_byte_cursor *hash, - const struct aws_byte_cursor *signature) { - struct libcrypto_ecc_key *libcrypto_key_pair = key_pair->impl; - - return ECDSA_verify(0, hash->ptr, hash->len, signature->ptr, signature->len, libcrypto_key_pair->ec_key) == 1 - ? AWS_OP_SUCCESS - : aws_raise_error(AWS_ERROR_CAL_SIGNATURE_VALIDATION_FAILED); -} - -static size_t s_signature_length(const struct aws_ecc_key_pair *key_pair) { - struct libcrypto_ecc_key *libcrypto_key_pair = key_pair->impl; - - return ECDSA_size(libcrypto_key_pair->ec_key); -} - -static int s_fill_in_public_key_info( - struct libcrypto_ecc_key *libcrypto_key_pair, - const EC_GROUP *group, - const EC_POINT *pub_key_point) { - BIGNUM *big_num_x = BN_new(); - BIGNUM *big_num_y = BN_new(); - - int ret_val = AWS_OP_ERR; - - if (EC_POINT_get_affine_coordinates_GFp(group, pub_key_point, big_num_x, big_num_y, NULL) != 1) { - aws_raise_error(AWS_ERROR_INVALID_STATE); - goto clean_up; - } - - size_t x_coor_size = BN_num_bytes(big_num_x); - size_t y_coor_size = BN_num_bytes(big_num_y); - - if (aws_byte_buf_init(&libcrypto_key_pair->key_pair.pub_x, libcrypto_key_pair->key_pair.allocator, x_coor_size)) { - goto clean_up; - } - - if (aws_byte_buf_init(&libcrypto_key_pair->key_pair.pub_y, libcrypto_key_pair->key_pair.allocator, y_coor_size)) { - goto clean_up; - } - - BN_bn2bin(big_num_x, libcrypto_key_pair->key_pair.pub_x.buffer); - BN_bn2bin(big_num_y, libcrypto_key_pair->key_pair.pub_y.buffer); - - libcrypto_key_pair->key_pair.pub_x.len = x_coor_size; - libcrypto_key_pair->key_pair.pub_y.len = y_coor_size; - - ret_val = AWS_OP_SUCCESS; - -clean_up: - BN_free(big_num_x); - BN_free(big_num_y); - - return ret_val; -} - -static int s_derive_public_key(struct aws_ecc_key_pair *key_pair) { - struct libcrypto_ecc_key *libcrypto_key_pair = key_pair->impl; - - if (!libcrypto_key_pair->key_pair.priv_d.buffer) { - return aws_raise_error(AWS_ERROR_INVALID_STATE); - } - - /* we already have a public key. */ - if (libcrypto_key_pair->key_pair.pub_x.len) { - return AWS_OP_SUCCESS; - } - - BIGNUM *priv_key_num = - BN_bin2bn(libcrypto_key_pair->key_pair.priv_d.buffer, libcrypto_key_pair->key_pair.priv_d.len, NULL); - - const EC_GROUP *group = EC_KEY_get0_group(libcrypto_key_pair->ec_key); - EC_POINT *point = EC_POINT_new(group); - - EC_POINT_mul(group, point, priv_key_num, NULL, NULL, NULL); - BN_free(priv_key_num); - - EC_KEY_set_public_key(libcrypto_key_pair->ec_key, point); - int ret_val = s_fill_in_public_key_info(libcrypto_key_pair, group, point); - EC_POINT_free(point); - return ret_val; -} - -static struct aws_ecc_key_pair_vtable vtable = { - .sign_message = s_sign_payload, - .verify_signature = s_verify_payload, - .derive_pub_key = s_derive_public_key, - .signature_length = s_signature_length, - .destroy = s_key_pair_destroy, -}; - -struct aws_ecc_key_pair *aws_ecc_key_pair_new_from_private_key( - struct aws_allocator *allocator, - enum aws_ecc_curve_name curve_name, - const struct aws_byte_cursor *priv_key) { - - size_t key_length = aws_ecc_key_coordinate_byte_size_from_curve_name(curve_name); - if (priv_key->len != key_length) { - aws_raise_error(AWS_ERROR_CAL_INVALID_KEY_LENGTH_FOR_ALGORITHM); - return NULL; - } - - struct libcrypto_ecc_key *key_impl = aws_mem_calloc(allocator, 1, sizeof(struct libcrypto_ecc_key)); - - key_impl->ec_key = EC_KEY_new_by_curve_name(s_curve_name_to_nid(curve_name)); - key_impl->key_pair.curve_name = curve_name; - key_impl->key_pair.allocator = allocator; - key_impl->key_pair.vtable = &vtable; - key_impl->key_pair.impl = key_impl; - aws_atomic_init_int(&key_impl->key_pair.ref_count, 1); - aws_byte_buf_init_copy_from_cursor(&key_impl->key_pair.priv_d, allocator, *priv_key); - - BIGNUM *priv_key_num = BN_bin2bn(key_impl->key_pair.priv_d.buffer, key_impl->key_pair.priv_d.len, NULL); - if (!EC_KEY_set_private_key(key_impl->ec_key, priv_key_num)) { - aws_raise_error(AWS_ERROR_INVALID_ARGUMENT); - BN_free(priv_key_num); - s_key_pair_destroy(&key_impl->key_pair); - return NULL; - } - BN_free(priv_key_num); - return &key_impl->key_pair; -} - -struct aws_ecc_key_pair *aws_ecc_key_pair_new_generate_random( - struct aws_allocator *allocator, - enum aws_ecc_curve_name curve_name) { - struct libcrypto_ecc_key *key_impl = aws_mem_calloc(allocator, 1, sizeof(struct libcrypto_ecc_key)); - - key_impl->ec_key = EC_KEY_new_by_curve_name(s_curve_name_to_nid(curve_name)); - key_impl->key_pair.curve_name = curve_name; - key_impl->key_pair.allocator = allocator; - key_impl->key_pair.vtable = &vtable; - key_impl->key_pair.impl = key_impl; - aws_atomic_init_int(&key_impl->key_pair.ref_count, 1); - - if (EC_KEY_generate_key(key_impl->ec_key) != 1) { - goto error; - } - - const EC_POINT *pub_key_point = EC_KEY_get0_public_key(key_impl->ec_key); - const EC_GROUP *group = EC_KEY_get0_group(key_impl->ec_key); - - const BIGNUM *private_key_num = EC_KEY_get0_private_key(key_impl->ec_key); - size_t priv_key_size = BN_num_bytes(private_key_num); - if (aws_byte_buf_init(&key_impl->key_pair.priv_d, allocator, priv_key_size)) { - goto error; - } - - BN_bn2bin(private_key_num, key_impl->key_pair.priv_d.buffer); - key_impl->key_pair.priv_d.len = priv_key_size; - - if (!s_fill_in_public_key_info(key_impl, group, pub_key_point)) { - return &key_impl->key_pair; - } - -error: - s_key_pair_destroy(&key_impl->key_pair); - return NULL; -} - -struct aws_ecc_key_pair *aws_ecc_key_pair_new_from_public_key( - struct aws_allocator *allocator, - enum aws_ecc_curve_name curve_name, - const struct aws_byte_cursor *public_key_x, - const struct aws_byte_cursor *public_key_y) { - struct libcrypto_ecc_key *key_impl = aws_mem_calloc(allocator, 1, sizeof(struct libcrypto_ecc_key)); - BIGNUM *pub_x_num = NULL; - BIGNUM *pub_y_num = NULL; - EC_POINT *point = NULL; - - if (!key_impl) { - return NULL; - } - - key_impl->ec_key = EC_KEY_new_by_curve_name(s_curve_name_to_nid(curve_name)); - key_impl->key_pair.curve_name = curve_name; - key_impl->key_pair.allocator = allocator; - key_impl->key_pair.vtable = &vtable; - key_impl->key_pair.impl = key_impl; - aws_atomic_init_int(&key_impl->key_pair.ref_count, 1); - - if (aws_byte_buf_init_copy_from_cursor(&key_impl->key_pair.pub_x, allocator, *public_key_x)) { - s_key_pair_destroy(&key_impl->key_pair); - return NULL; - } - - if (aws_byte_buf_init_copy_from_cursor(&key_impl->key_pair.pub_y, allocator, *public_key_y)) { - s_key_pair_destroy(&key_impl->key_pair); - return NULL; - } - - pub_x_num = BN_bin2bn(public_key_x->ptr, public_key_x->len, NULL); - pub_y_num = BN_bin2bn(public_key_y->ptr, public_key_y->len, NULL); - - const EC_GROUP *group = EC_KEY_get0_group(key_impl->ec_key); - point = EC_POINT_new(group); - - if (EC_POINT_set_affine_coordinates_GFp(group, point, pub_x_num, pub_y_num, NULL) != 1) { - goto error; - } - - if (EC_KEY_set_public_key(key_impl->ec_key, point) != 1) { - goto error; - } - - EC_POINT_free(point); - BN_free(pub_x_num); - BN_free(pub_y_num); - - return &key_impl->key_pair; - -error: - if (point) { - EC_POINT_free(point); - } - - if (pub_x_num) { - BN_free(pub_x_num); - } - - if (pub_y_num) { - BN_free(pub_y_num); - } - - s_key_pair_destroy(&key_impl->key_pair); - - return NULL; -} - -struct aws_ecc_key_pair *aws_ecc_key_pair_new_from_asn1( - struct aws_allocator *allocator, - const struct aws_byte_cursor *encoded_keys) { - - struct aws_ecc_key_pair *key = NULL; - struct aws_der_decoder *decoder = aws_der_decoder_new(allocator, *encoded_keys); - - if (!decoder) { - return NULL; - } - - struct aws_byte_cursor pub_x; - struct aws_byte_cursor pub_y; - struct aws_byte_cursor priv_d; - - enum aws_ecc_curve_name curve_name; - if (aws_der_decoder_load_ecc_key_pair(decoder, &pub_x, &pub_y, &priv_d, &curve_name)) { - goto error; - } - - if (priv_d.ptr) { - struct libcrypto_ecc_key *key_impl = aws_mem_calloc(allocator, 1, sizeof(struct libcrypto_ecc_key)); - key_impl->key_pair.curve_name = curve_name; - /* as awkward as it seems, there's not a great way to manually set the public key, so let openssl just parse - * the der document manually now that we know what parts are what. */ - if (!d2i_ECPrivateKey(&key_impl->ec_key, (const unsigned char **)&encoded_keys->ptr, encoded_keys->len)) { - aws_mem_release(allocator, key_impl); - aws_raise_error(AWS_ERROR_CAL_MISSING_REQUIRED_KEY_COMPONENT); - goto error; - } - - key_impl->key_pair.allocator = allocator; - key_impl->key_pair.vtable = &vtable; - key_impl->key_pair.impl = key_impl; - aws_atomic_init_int(&key_impl->key_pair.ref_count, 1); - key = &key_impl->key_pair; - - struct aws_byte_buf temp_buf; - AWS_ZERO_STRUCT(temp_buf); - - if (pub_x.ptr) { - temp_buf = aws_byte_buf_from_array(pub_x.ptr, pub_x.len); - if (aws_byte_buf_init_copy(&key->pub_x, allocator, &temp_buf)) { - goto error; - } - } - - if (pub_y.ptr) { - temp_buf = aws_byte_buf_from_array(pub_y.ptr, pub_y.len); - if (aws_byte_buf_init_copy(&key->pub_y, allocator, &temp_buf)) { - goto error; - } - } - - if (priv_d.ptr) { - temp_buf = aws_byte_buf_from_array(priv_d.ptr, priv_d.len); - if (aws_byte_buf_init_copy(&key->priv_d, allocator, &temp_buf)) { - goto error; - } - } - - } else { - key = aws_ecc_key_pair_new_from_public_key(allocator, curve_name, &pub_x, &pub_y); - - if (!key) { - goto error; - } - } - - aws_der_decoder_destroy(decoder); - return key; - -error: - aws_der_decoder_destroy(decoder); - s_key_pair_destroy(key); - - return NULL; -} +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ +#include <aws/cal/private/ecc.h> + +#include <aws/cal/cal.h> +#include <aws/cal/private/der.h> + +#include <openssl/bn.h> +#include <openssl/ec.h> +#include <openssl/ecdsa.h> +#include <openssl/obj_mac.h> + +struct libcrypto_ecc_key { + struct aws_ecc_key_pair key_pair; + EC_KEY *ec_key; +}; + +static int s_curve_name_to_nid(enum aws_ecc_curve_name curve_name) { + switch (curve_name) { + case AWS_CAL_ECDSA_P256: + return NID_X9_62_prime256v1; + case AWS_CAL_ECDSA_P384: + return NID_secp384r1; + } + + AWS_FATAL_ASSERT(!"Unsupported elliptic curve name"); + return -1; +} + +static void s_key_pair_destroy(struct aws_ecc_key_pair *key_pair) { + + if (key_pair) { + aws_byte_buf_clean_up(&key_pair->pub_x); + aws_byte_buf_clean_up(&key_pair->pub_y); + aws_byte_buf_clean_up_secure(&key_pair->priv_d); + + struct libcrypto_ecc_key *key_impl = key_pair->impl; + + if (key_impl->ec_key) { + EC_KEY_free(key_impl->ec_key); + } + aws_mem_release(key_pair->allocator, key_pair); + } +} + +static int s_sign_payload( + const struct aws_ecc_key_pair *key_pair, + const struct aws_byte_cursor *hash, + struct aws_byte_buf *signature_output) { + struct libcrypto_ecc_key *libcrypto_key_pair = key_pair->impl; + + unsigned int signature_size = signature_output->capacity - signature_output->len; + int ret_val = ECDSA_sign( + 0, + hash->ptr, + hash->len, + signature_output->buffer + signature_output->len, + &signature_size, + libcrypto_key_pair->ec_key); + signature_output->len += signature_size; + + return ret_val == 1 ? AWS_OP_SUCCESS : aws_raise_error(AWS_ERROR_INVALID_ARGUMENT); +} + +static int s_verify_payload( + const struct aws_ecc_key_pair *key_pair, + const struct aws_byte_cursor *hash, + const struct aws_byte_cursor *signature) { + struct libcrypto_ecc_key *libcrypto_key_pair = key_pair->impl; + + return ECDSA_verify(0, hash->ptr, hash->len, signature->ptr, signature->len, libcrypto_key_pair->ec_key) == 1 + ? AWS_OP_SUCCESS + : aws_raise_error(AWS_ERROR_CAL_SIGNATURE_VALIDATION_FAILED); +} + +static size_t s_signature_length(const struct aws_ecc_key_pair *key_pair) { + struct libcrypto_ecc_key *libcrypto_key_pair = key_pair->impl; + + return ECDSA_size(libcrypto_key_pair->ec_key); +} + +static int s_fill_in_public_key_info( + struct libcrypto_ecc_key *libcrypto_key_pair, + const EC_GROUP *group, + const EC_POINT *pub_key_point) { + BIGNUM *big_num_x = BN_new(); + BIGNUM *big_num_y = BN_new(); + + int ret_val = AWS_OP_ERR; + + if (EC_POINT_get_affine_coordinates_GFp(group, pub_key_point, big_num_x, big_num_y, NULL) != 1) { + aws_raise_error(AWS_ERROR_INVALID_STATE); + goto clean_up; + } + + size_t x_coor_size = BN_num_bytes(big_num_x); + size_t y_coor_size = BN_num_bytes(big_num_y); + + if (aws_byte_buf_init(&libcrypto_key_pair->key_pair.pub_x, libcrypto_key_pair->key_pair.allocator, x_coor_size)) { + goto clean_up; + } + + if (aws_byte_buf_init(&libcrypto_key_pair->key_pair.pub_y, libcrypto_key_pair->key_pair.allocator, y_coor_size)) { + goto clean_up; + } + + BN_bn2bin(big_num_x, libcrypto_key_pair->key_pair.pub_x.buffer); + BN_bn2bin(big_num_y, libcrypto_key_pair->key_pair.pub_y.buffer); + + libcrypto_key_pair->key_pair.pub_x.len = x_coor_size; + libcrypto_key_pair->key_pair.pub_y.len = y_coor_size; + + ret_val = AWS_OP_SUCCESS; + +clean_up: + BN_free(big_num_x); + BN_free(big_num_y); + + return ret_val; +} + +static int s_derive_public_key(struct aws_ecc_key_pair *key_pair) { + struct libcrypto_ecc_key *libcrypto_key_pair = key_pair->impl; + + if (!libcrypto_key_pair->key_pair.priv_d.buffer) { + return aws_raise_error(AWS_ERROR_INVALID_STATE); + } + + /* we already have a public key. */ + if (libcrypto_key_pair->key_pair.pub_x.len) { + return AWS_OP_SUCCESS; + } + + BIGNUM *priv_key_num = + BN_bin2bn(libcrypto_key_pair->key_pair.priv_d.buffer, libcrypto_key_pair->key_pair.priv_d.len, NULL); + + const EC_GROUP *group = EC_KEY_get0_group(libcrypto_key_pair->ec_key); + EC_POINT *point = EC_POINT_new(group); + + EC_POINT_mul(group, point, priv_key_num, NULL, NULL, NULL); + BN_free(priv_key_num); + + EC_KEY_set_public_key(libcrypto_key_pair->ec_key, point); + int ret_val = s_fill_in_public_key_info(libcrypto_key_pair, group, point); + EC_POINT_free(point); + return ret_val; +} + +static struct aws_ecc_key_pair_vtable vtable = { + .sign_message = s_sign_payload, + .verify_signature = s_verify_payload, + .derive_pub_key = s_derive_public_key, + .signature_length = s_signature_length, + .destroy = s_key_pair_destroy, +}; + +struct aws_ecc_key_pair *aws_ecc_key_pair_new_from_private_key( + struct aws_allocator *allocator, + enum aws_ecc_curve_name curve_name, + const struct aws_byte_cursor *priv_key) { + + size_t key_length = aws_ecc_key_coordinate_byte_size_from_curve_name(curve_name); + if (priv_key->len != key_length) { + aws_raise_error(AWS_ERROR_CAL_INVALID_KEY_LENGTH_FOR_ALGORITHM); + return NULL; + } + + struct libcrypto_ecc_key *key_impl = aws_mem_calloc(allocator, 1, sizeof(struct libcrypto_ecc_key)); + + key_impl->ec_key = EC_KEY_new_by_curve_name(s_curve_name_to_nid(curve_name)); + key_impl->key_pair.curve_name = curve_name; + key_impl->key_pair.allocator = allocator; + key_impl->key_pair.vtable = &vtable; + key_impl->key_pair.impl = key_impl; + aws_atomic_init_int(&key_impl->key_pair.ref_count, 1); + aws_byte_buf_init_copy_from_cursor(&key_impl->key_pair.priv_d, allocator, *priv_key); + + BIGNUM *priv_key_num = BN_bin2bn(key_impl->key_pair.priv_d.buffer, key_impl->key_pair.priv_d.len, NULL); + if (!EC_KEY_set_private_key(key_impl->ec_key, priv_key_num)) { + aws_raise_error(AWS_ERROR_INVALID_ARGUMENT); + BN_free(priv_key_num); + s_key_pair_destroy(&key_impl->key_pair); + return NULL; + } + BN_free(priv_key_num); + return &key_impl->key_pair; +} + +struct aws_ecc_key_pair *aws_ecc_key_pair_new_generate_random( + struct aws_allocator *allocator, + enum aws_ecc_curve_name curve_name) { + struct libcrypto_ecc_key *key_impl = aws_mem_calloc(allocator, 1, sizeof(struct libcrypto_ecc_key)); + + key_impl->ec_key = EC_KEY_new_by_curve_name(s_curve_name_to_nid(curve_name)); + key_impl->key_pair.curve_name = curve_name; + key_impl->key_pair.allocator = allocator; + key_impl->key_pair.vtable = &vtable; + key_impl->key_pair.impl = key_impl; + aws_atomic_init_int(&key_impl->key_pair.ref_count, 1); + + if (EC_KEY_generate_key(key_impl->ec_key) != 1) { + goto error; + } + + const EC_POINT *pub_key_point = EC_KEY_get0_public_key(key_impl->ec_key); + const EC_GROUP *group = EC_KEY_get0_group(key_impl->ec_key); + + const BIGNUM *private_key_num = EC_KEY_get0_private_key(key_impl->ec_key); + size_t priv_key_size = BN_num_bytes(private_key_num); + if (aws_byte_buf_init(&key_impl->key_pair.priv_d, allocator, priv_key_size)) { + goto error; + } + + BN_bn2bin(private_key_num, key_impl->key_pair.priv_d.buffer); + key_impl->key_pair.priv_d.len = priv_key_size; + + if (!s_fill_in_public_key_info(key_impl, group, pub_key_point)) { + return &key_impl->key_pair; + } + +error: + s_key_pair_destroy(&key_impl->key_pair); + return NULL; +} + +struct aws_ecc_key_pair *aws_ecc_key_pair_new_from_public_key( + struct aws_allocator *allocator, + enum aws_ecc_curve_name curve_name, + const struct aws_byte_cursor *public_key_x, + const struct aws_byte_cursor *public_key_y) { + struct libcrypto_ecc_key *key_impl = aws_mem_calloc(allocator, 1, sizeof(struct libcrypto_ecc_key)); + BIGNUM *pub_x_num = NULL; + BIGNUM *pub_y_num = NULL; + EC_POINT *point = NULL; + + if (!key_impl) { + return NULL; + } + + key_impl->ec_key = EC_KEY_new_by_curve_name(s_curve_name_to_nid(curve_name)); + key_impl->key_pair.curve_name = curve_name; + key_impl->key_pair.allocator = allocator; + key_impl->key_pair.vtable = &vtable; + key_impl->key_pair.impl = key_impl; + aws_atomic_init_int(&key_impl->key_pair.ref_count, 1); + + if (aws_byte_buf_init_copy_from_cursor(&key_impl->key_pair.pub_x, allocator, *public_key_x)) { + s_key_pair_destroy(&key_impl->key_pair); + return NULL; + } + + if (aws_byte_buf_init_copy_from_cursor(&key_impl->key_pair.pub_y, allocator, *public_key_y)) { + s_key_pair_destroy(&key_impl->key_pair); + return NULL; + } + + pub_x_num = BN_bin2bn(public_key_x->ptr, public_key_x->len, NULL); + pub_y_num = BN_bin2bn(public_key_y->ptr, public_key_y->len, NULL); + + const EC_GROUP *group = EC_KEY_get0_group(key_impl->ec_key); + point = EC_POINT_new(group); + + if (EC_POINT_set_affine_coordinates_GFp(group, point, pub_x_num, pub_y_num, NULL) != 1) { + goto error; + } + + if (EC_KEY_set_public_key(key_impl->ec_key, point) != 1) { + goto error; + } + + EC_POINT_free(point); + BN_free(pub_x_num); + BN_free(pub_y_num); + + return &key_impl->key_pair; + +error: + if (point) { + EC_POINT_free(point); + } + + if (pub_x_num) { + BN_free(pub_x_num); + } + + if (pub_y_num) { + BN_free(pub_y_num); + } + + s_key_pair_destroy(&key_impl->key_pair); + + return NULL; +} + +struct aws_ecc_key_pair *aws_ecc_key_pair_new_from_asn1( + struct aws_allocator *allocator, + const struct aws_byte_cursor *encoded_keys) { + + struct aws_ecc_key_pair *key = NULL; + struct aws_der_decoder *decoder = aws_der_decoder_new(allocator, *encoded_keys); + + if (!decoder) { + return NULL; + } + + struct aws_byte_cursor pub_x; + struct aws_byte_cursor pub_y; + struct aws_byte_cursor priv_d; + + enum aws_ecc_curve_name curve_name; + if (aws_der_decoder_load_ecc_key_pair(decoder, &pub_x, &pub_y, &priv_d, &curve_name)) { + goto error; + } + + if (priv_d.ptr) { + struct libcrypto_ecc_key *key_impl = aws_mem_calloc(allocator, 1, sizeof(struct libcrypto_ecc_key)); + key_impl->key_pair.curve_name = curve_name; + /* as awkward as it seems, there's not a great way to manually set the public key, so let openssl just parse + * the der document manually now that we know what parts are what. */ + if (!d2i_ECPrivateKey(&key_impl->ec_key, (const unsigned char **)&encoded_keys->ptr, encoded_keys->len)) { + aws_mem_release(allocator, key_impl); + aws_raise_error(AWS_ERROR_CAL_MISSING_REQUIRED_KEY_COMPONENT); + goto error; + } + + key_impl->key_pair.allocator = allocator; + key_impl->key_pair.vtable = &vtable; + key_impl->key_pair.impl = key_impl; + aws_atomic_init_int(&key_impl->key_pair.ref_count, 1); + key = &key_impl->key_pair; + + struct aws_byte_buf temp_buf; + AWS_ZERO_STRUCT(temp_buf); + + if (pub_x.ptr) { + temp_buf = aws_byte_buf_from_array(pub_x.ptr, pub_x.len); + if (aws_byte_buf_init_copy(&key->pub_x, allocator, &temp_buf)) { + goto error; + } + } + + if (pub_y.ptr) { + temp_buf = aws_byte_buf_from_array(pub_y.ptr, pub_y.len); + if (aws_byte_buf_init_copy(&key->pub_y, allocator, &temp_buf)) { + goto error; + } + } + + if (priv_d.ptr) { + temp_buf = aws_byte_buf_from_array(priv_d.ptr, priv_d.len); + if (aws_byte_buf_init_copy(&key->priv_d, allocator, &temp_buf)) { + goto error; + } + } + + } else { + key = aws_ecc_key_pair_new_from_public_key(allocator, curve_name, &pub_x, &pub_y); + + if (!key) { + goto error; + } + } + + aws_der_decoder_destroy(decoder); + return key; + +error: + aws_der_decoder_destroy(decoder); + s_key_pair_destroy(key); + + return NULL; +} diff --git a/contrib/restricted/aws/aws-c-cal/source/unix/opensslcrypto_hash.c b/contrib/restricted/aws/aws-c-cal/source/unix/opensslcrypto_hash.c index 05422a6f16..e74237eec4 100644 --- a/contrib/restricted/aws/aws-c-cal/source/unix/opensslcrypto_hash.c +++ b/contrib/restricted/aws/aws-c-cal/source/unix/opensslcrypto_hash.c @@ -1,139 +1,139 @@ -/** - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0. - */ -#include <aws/cal/hash.h> -#include <aws/cal/private/opensslcrypto_common.h> - -#include <openssl/evp.h> -#include <openssl/sha.h> - -static void s_destroy(struct aws_hash *hash); -static int s_update(struct aws_hash *hash, const struct aws_byte_cursor *to_hash); -static int s_finalize(struct aws_hash *hash, struct aws_byte_buf *output); - -static struct aws_hash_vtable s_md5_vtable = { - .destroy = s_destroy, - .update = s_update, - .finalize = s_finalize, - .alg_name = "MD5", - .provider = "OpenSSL Compatible libcrypto", -}; - -static struct aws_hash_vtable s_sha256_vtable = { - .destroy = s_destroy, - .update = s_update, - .finalize = s_finalize, - .alg_name = "SHA256", - .provider = "OpenSSL Compatible libcrypto", -}; - -static void s_destroy(struct aws_hash *hash) { - if (hash == NULL) { - return; - } - - EVP_MD_CTX *ctx = hash->impl; - if (ctx != NULL) { - g_aws_openssl_evp_md_ctx_table->free_fn(ctx); - } - - aws_mem_release(hash->allocator, hash); -} - -struct aws_hash *aws_md5_default_new(struct aws_allocator *allocator) { - struct aws_hash *hash = aws_mem_acquire(allocator, sizeof(struct aws_hash)); - - if (!hash) { - return NULL; - } - - hash->allocator = allocator; - hash->vtable = &s_md5_vtable; - hash->digest_size = AWS_MD5_LEN; - EVP_MD_CTX *ctx = g_aws_openssl_evp_md_ctx_table->new_fn(); - hash->impl = ctx; - hash->good = true; - - if (!hash->impl) { - s_destroy(hash); - aws_raise_error(AWS_ERROR_OOM); - return NULL; - } - - if (!g_aws_openssl_evp_md_ctx_table->init_ex_fn(ctx, EVP_md5(), NULL)) { - s_destroy(hash); - aws_raise_error(AWS_ERROR_UNKNOWN); - return NULL; - } - - return hash; -} - -struct aws_hash *aws_sha256_default_new(struct aws_allocator *allocator) { - struct aws_hash *hash = aws_mem_acquire(allocator, sizeof(struct aws_hash)); - - if (!hash) { - return NULL; - } - - hash->allocator = allocator; - hash->vtable = &s_sha256_vtable; - hash->digest_size = AWS_SHA256_LEN; - EVP_MD_CTX *ctx = g_aws_openssl_evp_md_ctx_table->new_fn(); - hash->impl = ctx; - hash->good = true; - - if (!hash->impl) { - s_destroy(hash); - aws_raise_error(AWS_ERROR_OOM); - return NULL; - } - - if (!g_aws_openssl_evp_md_ctx_table->init_ex_fn(ctx, EVP_sha256(), NULL)) { - s_destroy(hash); - aws_raise_error(AWS_ERROR_UNKNOWN); - return NULL; - } - - return hash; -} - -static int s_update(struct aws_hash *hash, const struct aws_byte_cursor *to_hash) { - if (!hash->good) { - return aws_raise_error(AWS_ERROR_INVALID_STATE); - } - - EVP_MD_CTX *ctx = hash->impl; - - if (AWS_LIKELY(g_aws_openssl_evp_md_ctx_table->update_fn(ctx, to_hash->ptr, to_hash->len))) { - return AWS_OP_SUCCESS; - } - - hash->good = false; - return aws_raise_error(AWS_ERROR_INVALID_ARGUMENT); -} - -static int s_finalize(struct aws_hash *hash, struct aws_byte_buf *output) { - if (!hash->good) { - return aws_raise_error(AWS_ERROR_INVALID_STATE); - } - - EVP_MD_CTX *ctx = hash->impl; - - size_t buffer_len = output->capacity - output->len; - - if (buffer_len < hash->digest_size) { - return aws_raise_error(AWS_ERROR_SHORT_BUFFER); - } - - if (AWS_LIKELY(g_aws_openssl_evp_md_ctx_table->final_ex_fn( - ctx, output->buffer + output->len, (unsigned int *)&buffer_len))) { - output->len += buffer_len; - hash->good = false; - return AWS_OP_SUCCESS; - } - - hash->good = false; - return aws_raise_error(AWS_ERROR_INVALID_ARGUMENT); -} +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ +#include <aws/cal/hash.h> +#include <aws/cal/private/opensslcrypto_common.h> + +#include <openssl/evp.h> +#include <openssl/sha.h> + +static void s_destroy(struct aws_hash *hash); +static int s_update(struct aws_hash *hash, const struct aws_byte_cursor *to_hash); +static int s_finalize(struct aws_hash *hash, struct aws_byte_buf *output); + +static struct aws_hash_vtable s_md5_vtable = { + .destroy = s_destroy, + .update = s_update, + .finalize = s_finalize, + .alg_name = "MD5", + .provider = "OpenSSL Compatible libcrypto", +}; + +static struct aws_hash_vtable s_sha256_vtable = { + .destroy = s_destroy, + .update = s_update, + .finalize = s_finalize, + .alg_name = "SHA256", + .provider = "OpenSSL Compatible libcrypto", +}; + +static void s_destroy(struct aws_hash *hash) { + if (hash == NULL) { + return; + } + + EVP_MD_CTX *ctx = hash->impl; + if (ctx != NULL) { + g_aws_openssl_evp_md_ctx_table->free_fn(ctx); + } + + aws_mem_release(hash->allocator, hash); +} + +struct aws_hash *aws_md5_default_new(struct aws_allocator *allocator) { + struct aws_hash *hash = aws_mem_acquire(allocator, sizeof(struct aws_hash)); + + if (!hash) { + return NULL; + } + + hash->allocator = allocator; + hash->vtable = &s_md5_vtable; + hash->digest_size = AWS_MD5_LEN; + EVP_MD_CTX *ctx = g_aws_openssl_evp_md_ctx_table->new_fn(); + hash->impl = ctx; + hash->good = true; + + if (!hash->impl) { + s_destroy(hash); + aws_raise_error(AWS_ERROR_OOM); + return NULL; + } + + if (!g_aws_openssl_evp_md_ctx_table->init_ex_fn(ctx, EVP_md5(), NULL)) { + s_destroy(hash); + aws_raise_error(AWS_ERROR_UNKNOWN); + return NULL; + } + + return hash; +} + +struct aws_hash *aws_sha256_default_new(struct aws_allocator *allocator) { + struct aws_hash *hash = aws_mem_acquire(allocator, sizeof(struct aws_hash)); + + if (!hash) { + return NULL; + } + + hash->allocator = allocator; + hash->vtable = &s_sha256_vtable; + hash->digest_size = AWS_SHA256_LEN; + EVP_MD_CTX *ctx = g_aws_openssl_evp_md_ctx_table->new_fn(); + hash->impl = ctx; + hash->good = true; + + if (!hash->impl) { + s_destroy(hash); + aws_raise_error(AWS_ERROR_OOM); + return NULL; + } + + if (!g_aws_openssl_evp_md_ctx_table->init_ex_fn(ctx, EVP_sha256(), NULL)) { + s_destroy(hash); + aws_raise_error(AWS_ERROR_UNKNOWN); + return NULL; + } + + return hash; +} + +static int s_update(struct aws_hash *hash, const struct aws_byte_cursor *to_hash) { + if (!hash->good) { + return aws_raise_error(AWS_ERROR_INVALID_STATE); + } + + EVP_MD_CTX *ctx = hash->impl; + + if (AWS_LIKELY(g_aws_openssl_evp_md_ctx_table->update_fn(ctx, to_hash->ptr, to_hash->len))) { + return AWS_OP_SUCCESS; + } + + hash->good = false; + return aws_raise_error(AWS_ERROR_INVALID_ARGUMENT); +} + +static int s_finalize(struct aws_hash *hash, struct aws_byte_buf *output) { + if (!hash->good) { + return aws_raise_error(AWS_ERROR_INVALID_STATE); + } + + EVP_MD_CTX *ctx = hash->impl; + + size_t buffer_len = output->capacity - output->len; + + if (buffer_len < hash->digest_size) { + return aws_raise_error(AWS_ERROR_SHORT_BUFFER); + } + + if (AWS_LIKELY(g_aws_openssl_evp_md_ctx_table->final_ex_fn( + ctx, output->buffer + output->len, (unsigned int *)&buffer_len))) { + output->len += buffer_len; + hash->good = false; + return AWS_OP_SUCCESS; + } + + hash->good = false; + return aws_raise_error(AWS_ERROR_INVALID_ARGUMENT); +} diff --git a/contrib/restricted/aws/aws-c-cal/source/unix/opensslcrypto_hmac.c b/contrib/restricted/aws/aws-c-cal/source/unix/opensslcrypto_hmac.c index c44295aae0..b040ffdf5c 100644 --- a/contrib/restricted/aws/aws-c-cal/source/unix/opensslcrypto_hmac.c +++ b/contrib/restricted/aws/aws-c-cal/source/unix/opensslcrypto_hmac.c @@ -1,122 +1,122 @@ -/** - * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. - * SPDX-License-Identifier: Apache-2.0. - */ -#include <aws/cal/hmac.h> -#include <aws/cal/private/opensslcrypto_common.h> - -#include <openssl/evp.h> -#include <openssl/hmac.h> - -static void s_destroy(struct aws_hmac *hmac); -static int s_update(struct aws_hmac *hmac, const struct aws_byte_cursor *to_hmac); -static int s_finalize(struct aws_hmac *hmac, struct aws_byte_buf *output); - -static struct aws_hmac_vtable s_sha256_hmac_vtable = { - .destroy = s_destroy, - .update = s_update, - .finalize = s_finalize, - .alg_name = "SHA256 HMAC", - .provider = "OpenSSL Compatible libcrypto", -}; - -static void s_destroy(struct aws_hmac *hmac) { - if (hmac == NULL) { - return; - } - - HMAC_CTX *ctx = hmac->impl; - if (ctx != NULL) { - g_aws_openssl_hmac_ctx_table->free_fn(ctx); - } - - aws_mem_release(hmac->allocator, hmac); -} - -/* -typedef struct hmac_ctx_st { - const EVP_MD *md; - EVP_MD_CTX md_ctx; - EVP_MD_CTX i_ctx; - EVP_MD_CTX o_ctx; - unsigned int key_length; - unsigned char key[HMAC_MAX_MD_CBLOCK]; -} HMAC_CTX; - -*/ - -#define SIZEOF_OPENSSL_HMAC_CTX 300 /* <= 288 on 64 bit systems with openssl 1.0.* */ - -struct aws_hmac *aws_sha256_hmac_default_new(struct aws_allocator *allocator, const struct aws_byte_cursor *secret) { - AWS_ASSERT(secret->ptr); - - struct aws_hmac *hmac = aws_mem_acquire(allocator, sizeof(struct aws_hmac)); - - if (!hmac) { - return NULL; - } - - hmac->allocator = allocator; - hmac->vtable = &s_sha256_hmac_vtable; - hmac->digest_size = AWS_SHA256_HMAC_LEN; - HMAC_CTX *ctx = NULL; - ctx = g_aws_openssl_hmac_ctx_table->new_fn(); - - if (!ctx) { - aws_raise_error(AWS_ERROR_OOM); - aws_mem_release(allocator, hmac); - return NULL; - } - - g_aws_openssl_hmac_ctx_table->init_fn(ctx); - - hmac->impl = ctx; - hmac->good = true; - - if (!g_aws_openssl_hmac_ctx_table->init_ex_fn(ctx, secret->ptr, (int)secret->len, EVP_sha256(), NULL)) { - s_destroy(hmac); - aws_raise_error(AWS_ERROR_INVALID_ARGUMENT); - return NULL; - } - - return hmac; -} - -static int s_update(struct aws_hmac *hmac, const struct aws_byte_cursor *to_hmac) { - if (!hmac->good) { - return aws_raise_error(AWS_ERROR_INVALID_STATE); - } - - HMAC_CTX *ctx = hmac->impl; - - if (AWS_LIKELY(g_aws_openssl_hmac_ctx_table->update_fn(ctx, to_hmac->ptr, to_hmac->len))) { - return AWS_OP_SUCCESS; - } - - hmac->good = false; - return aws_raise_error(AWS_ERROR_INVALID_ARGUMENT); -} - -static int s_finalize(struct aws_hmac *hmac, struct aws_byte_buf *output) { - if (!hmac->good) { - return aws_raise_error(AWS_ERROR_INVALID_STATE); - } - - HMAC_CTX *ctx = hmac->impl; - - size_t buffer_len = output->capacity - output->len; - - if (buffer_len < hmac->digest_size) { - return aws_raise_error(AWS_ERROR_SHORT_BUFFER); - } - - if (AWS_LIKELY( - g_aws_openssl_hmac_ctx_table->final_fn(ctx, output->buffer + output->len, (unsigned int *)&buffer_len))) { - hmac->good = false; - output->len += buffer_len; - return AWS_OP_SUCCESS; - } - - hmac->good = false; - return aws_raise_error(AWS_ERROR_INVALID_ARGUMENT); -} +/** + * Copyright Amazon.com, Inc. or its affiliates. All Rights Reserved. + * SPDX-License-Identifier: Apache-2.0. + */ +#include <aws/cal/hmac.h> +#include <aws/cal/private/opensslcrypto_common.h> + +#include <openssl/evp.h> +#include <openssl/hmac.h> + +static void s_destroy(struct aws_hmac *hmac); +static int s_update(struct aws_hmac *hmac, const struct aws_byte_cursor *to_hmac); +static int s_finalize(struct aws_hmac *hmac, struct aws_byte_buf *output); + +static struct aws_hmac_vtable s_sha256_hmac_vtable = { + .destroy = s_destroy, + .update = s_update, + .finalize = s_finalize, + .alg_name = "SHA256 HMAC", + .provider = "OpenSSL Compatible libcrypto", +}; + +static void s_destroy(struct aws_hmac *hmac) { + if (hmac == NULL) { + return; + } + + HMAC_CTX *ctx = hmac->impl; + if (ctx != NULL) { + g_aws_openssl_hmac_ctx_table->free_fn(ctx); + } + + aws_mem_release(hmac->allocator, hmac); +} + +/* +typedef struct hmac_ctx_st { + const EVP_MD *md; + EVP_MD_CTX md_ctx; + EVP_MD_CTX i_ctx; + EVP_MD_CTX o_ctx; + unsigned int key_length; + unsigned char key[HMAC_MAX_MD_CBLOCK]; +} HMAC_CTX; + +*/ + +#define SIZEOF_OPENSSL_HMAC_CTX 300 /* <= 288 on 64 bit systems with openssl 1.0.* */ + +struct aws_hmac *aws_sha256_hmac_default_new(struct aws_allocator *allocator, const struct aws_byte_cursor *secret) { + AWS_ASSERT(secret->ptr); + + struct aws_hmac *hmac = aws_mem_acquire(allocator, sizeof(struct aws_hmac)); + + if (!hmac) { + return NULL; + } + + hmac->allocator = allocator; + hmac->vtable = &s_sha256_hmac_vtable; + hmac->digest_size = AWS_SHA256_HMAC_LEN; + HMAC_CTX *ctx = NULL; + ctx = g_aws_openssl_hmac_ctx_table->new_fn(); + + if (!ctx) { + aws_raise_error(AWS_ERROR_OOM); + aws_mem_release(allocator, hmac); + return NULL; + } + + g_aws_openssl_hmac_ctx_table->init_fn(ctx); + + hmac->impl = ctx; + hmac->good = true; + + if (!g_aws_openssl_hmac_ctx_table->init_ex_fn(ctx, secret->ptr, (int)secret->len, EVP_sha256(), NULL)) { + s_destroy(hmac); + aws_raise_error(AWS_ERROR_INVALID_ARGUMENT); + return NULL; + } + + return hmac; +} + +static int s_update(struct aws_hmac *hmac, const struct aws_byte_cursor *to_hmac) { + if (!hmac->good) { + return aws_raise_error(AWS_ERROR_INVALID_STATE); + } + + HMAC_CTX *ctx = hmac->impl; + + if (AWS_LIKELY(g_aws_openssl_hmac_ctx_table->update_fn(ctx, to_hmac->ptr, to_hmac->len))) { + return AWS_OP_SUCCESS; + } + + hmac->good = false; + return aws_raise_error(AWS_ERROR_INVALID_ARGUMENT); +} + +static int s_finalize(struct aws_hmac *hmac, struct aws_byte_buf *output) { + if (!hmac->good) { + return aws_raise_error(AWS_ERROR_INVALID_STATE); + } + + HMAC_CTX *ctx = hmac->impl; + + size_t buffer_len = output->capacity - output->len; + + if (buffer_len < hmac->digest_size) { + return aws_raise_error(AWS_ERROR_SHORT_BUFFER); + } + + if (AWS_LIKELY( + g_aws_openssl_hmac_ctx_table->final_fn(ctx, output->buffer + output->len, (unsigned int *)&buffer_len))) { + hmac->good = false; + output->len += buffer_len; + return AWS_OP_SUCCESS; + } + + hmac->good = false; + return aws_raise_error(AWS_ERROR_INVALID_ARGUMENT); +} diff --git a/contrib/restricted/aws/aws-c-cal/ya.make b/contrib/restricted/aws/aws-c-cal/ya.make index 522f585b59..9c4193a677 100644 --- a/contrib/restricted/aws/aws-c-cal/ya.make +++ b/contrib/restricted/aws/aws-c-cal/ya.make @@ -1,41 +1,41 @@ -# Generated by devtools/yamaker. - -LIBRARY() - +# Generated by devtools/yamaker. + +LIBRARY() + OWNER( orivej g:cpp-contrib ) - -VERSION(0.4.5) - -LICENSE(Apache-2.0) - + +VERSION(0.4.5) + +LICENSE(Apache-2.0) + LICENSE_TEXTS(.yandex_meta/licenses.list.txt) -PEERDIR( - contrib/libs/openssl - contrib/restricted/aws/aws-c-common -) - -ADDINCL( - GLOBAL contrib/restricted/aws/aws-c-cal/include -) - -NO_COMPILER_WARNINGS() - -NO_RUNTIME() - -SRCS( - source/cal.c - source/der.c - source/ecc.c - source/hash.c - source/hmac.c - source/unix/openssl_platform_init.c - source/unix/opensslcrypto_ecc.c - source/unix/opensslcrypto_hash.c - source/unix/opensslcrypto_hmac.c -) - -END() +PEERDIR( + contrib/libs/openssl + contrib/restricted/aws/aws-c-common +) + +ADDINCL( + GLOBAL contrib/restricted/aws/aws-c-cal/include +) + +NO_COMPILER_WARNINGS() + +NO_RUNTIME() + +SRCS( + source/cal.c + source/der.c + source/ecc.c + source/hash.c + source/hmac.c + source/unix/openssl_platform_init.c + source/unix/opensslcrypto_ecc.c + source/unix/opensslcrypto_hash.c + source/unix/opensslcrypto_hmac.c +) + +END() |