From 4c6d16b42153254406bb1b0ea39a4bccd2713522 Mon Sep 17 00:00:00 2001 From: Panu Matilainen Date: Wed, 20 Mar 2024 13:55:38 +0200 Subject: [PATCH] Split off the internal OpenPGP parser to a separate repository Now that we have an alternative to building without Rust, it's time to say bye to this old thing. We will not support the parser but preserve minimal hooks in cmake to allow building with it, at least for a transition period: https://github.com/rpm-software-management/rpmpgp_legacy Fixes: #2414 --- rpmio/rpmpgp_legacy/CMakeLists.txt | 17 - rpmio/rpmpgp_legacy/COPYING | 830 -------------- rpmio/rpmpgp_legacy/README | 15 - rpmio/rpmpgp_legacy/digest_libgcrypt.c | 445 -------- rpmio/rpmpgp_legacy/digest_openssl.c | 691 ------------ rpmio/rpmpgp_legacy/rpmpgp_internal.c | 1423 ------------------------ rpmio/rpmpgp_legacy/rpmpgp_internal.h | 50 - 7 files changed, 3471 deletions(-) delete mode 100644 rpmio/rpmpgp_legacy/CMakeLists.txt delete mode 100644 rpmio/rpmpgp_legacy/COPYING delete mode 100644 rpmio/rpmpgp_legacy/README delete mode 100644 rpmio/rpmpgp_legacy/digest_libgcrypt.c delete mode 100644 rpmio/rpmpgp_legacy/digest_openssl.c delete mode 100644 rpmio/rpmpgp_legacy/rpmpgp_internal.c delete mode 100644 rpmio/rpmpgp_legacy/rpmpgp_internal.h diff --git a/rpmio/rpmpgp_legacy/CMakeLists.txt b/rpmio/rpmpgp_legacy/CMakeLists.txt deleted file mode 100644 index 02c26d1e56..0000000000 --- a/rpmio/rpmpgp_legacy/CMakeLists.txt +++ /dev/null @@ -1,17 +0,0 @@ -# At least for now, this is can't be built as a standalone project. Ie, -# it can only be built as a part of rpm build tree. -add_library(rpmpgp_legacy OBJECT) - -option(WITH_LEGACY_OPENPGP "Use legacy OpenPGP parser (DEPRECATED)" OFF) - -target_sources(rpmpgp_legacy PRIVATE - rpmpgp_internal.h rpmpgp_internal.c -) -if (WITH_OPENSSL) - target_sources(rpmpgp_legacy PRIVATE digest_openssl.c) -else() - target_sources(rpmpgp_legacy PRIVATE digest_libgcrypt.c) -endif() -target_include_directories(rpmpgp_legacy PRIVATE ..) -target_include_directories(rpmpgp_legacy PRIVATE ${Intl_INCLUDE_DIRS}) - diff --git a/rpmio/rpmpgp_legacy/COPYING b/rpmio/rpmpgp_legacy/COPYING deleted file mode 100644 index 77a78fe8f2..0000000000 --- a/rpmio/rpmpgp_legacy/COPYING +++ /dev/null @@ -1,830 +0,0 @@ - -The rpmpgp_legacy code may be distributed under the terms of the GNU General -Public License (GPL) or under the GNU Library General Public License (LGPL). -The complete text of both licenses is supplied below. - ---------------------------------------------------------------------------- - - GNU GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1989, 1991 Free Software Foundation, Inc. - 675 Mass Ave, Cambridge, MA 02139, USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -License is intended to guarantee your freedom to share and change free -software--to make sure the software is free for all its users. This -General Public License applies to most of the Free Software -Foundation's software and to any other program whose authors commit to -using it. (Some other Free Software Foundation software is covered by -the GNU Library General Public License instead.) You can apply it to -your programs, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if you -distribute copies of the software, or if you modify it. - - For example, if you distribute copies of such a program, whether -gratis or for a fee, you must give the recipients all the rights that -you have. You must make sure that they, too, receive or can get the -source code. And you must show them these terms so they know their -rights. - - We protect your rights with two steps: (1) copyright the software, and -(2) offer you this license which gives you legal permission to copy, -distribute and/or modify the software. - - Also, for each author's protection and ours, we want to make certain -that everyone understands that there is no warranty for this free -software. If the software is modified by someone else and passed on, we -want its recipients to know that what they have is not the original, so -that any problems introduced by others will not reflect on the original -authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that redistributors of a free -program will individually obtain patent licenses, in effect making the -program proprietary. To prevent this, we have made it clear that any -patent must be licensed for everyone's free use or not licensed at all. - - The precise terms and conditions for copying, distribution and -modification follow. - - GNU GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License applies to any program or other work which contains -a notice placed by the copyright holder saying it may be distributed -under the terms of this General Public License. The "Program", below, -refers to any such program or work, and a "work based on the Program" -means either the Program or any derivative work under copyright law: -that is to say, a work containing the Program or a portion of it, -either verbatim or with modifications and/or translated into another -language. (Hereinafter, translation is included without limitation in -the term "modification".) Each licensee is addressed as "you". - -Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running the Program is not restricted, and the output from the Program -is covered only if its contents constitute a work based on the -Program (independent of having been made by running the Program). -Whether that is true depends on what the Program does. - - 1. You may copy and distribute verbatim copies of the Program's -source code as you receive it, in any medium, provided that you -conspicuously and appropriately publish on each copy an appropriate -copyright notice and disclaimer of warranty; keep intact all the -notices that refer to this License and to the absence of any warranty; -and give any other recipients of the Program a copy of this License -along with the Program. - -You may charge a fee for the physical act of transferring a copy, and -you may at your option offer warranty protection in exchange for a fee. - - 2. You may modify your copy or copies of the Program or any portion -of it, thus forming a work based on the Program, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) You must cause the modified files to carry prominent notices - stating that you changed the files and the date of any change. - - b) You must cause any work that you distribute or publish, that in - whole or in part contains or is derived from the Program or any - part thereof, to be licensed as a whole at no charge to all third - parties under the terms of this License. - - c) If the modified program normally reads commands interactively - when run, you must cause it, when started running for such - interactive use in the most ordinary way, to print or display an - announcement including an appropriate copyright notice and a - notice that there is no warranty (or else, saying that you provide - a warranty) and that users may redistribute the program under - these conditions, and telling the user how to view a copy of this - License. (Exception: if the Program itself is interactive but - does not normally print such an announcement, your work based on - the Program is not required to print an announcement.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Program, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Program, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Program. - -In addition, mere aggregation of another work not based on the Program -with the Program (or with a work based on the Program) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may copy and distribute the Program (or a work based on it, -under Section 2) in object code or executable form under the terms of -Sections 1 and 2 above provided that you also do one of the following: - - a) Accompany it with the complete corresponding machine-readable - source code, which must be distributed under the terms of Sections - 1 and 2 above on a medium customarily used for software interchange; or, - - b) Accompany it with a written offer, valid for at least three - years, to give any third party, for a charge no more than your - cost of physically performing source distribution, a complete - machine-readable copy of the corresponding source code, to be - distributed under the terms of Sections 1 and 2 above on a medium - customarily used for software interchange; or, - - c) Accompany it with the information you received as to the offer - to distribute corresponding source code. (This alternative is - allowed only for noncommercial distribution and only if you - received the program in object code or executable form with such - an offer, in accord with Subsection b above.) - -The source code for a work means the preferred form of the work for -making modifications to it. For an executable work, complete source -code means all the source code for all modules it contains, plus any -associated interface definition files, plus the scripts used to -control compilation and installation of the executable. However, as a -special exception, the source code distributed need not include -anything that is normally distributed (in either source or binary -form) with the major components (compiler, kernel, and so on) of the -operating system on which the executable runs, unless that component -itself accompanies the executable. - -If distribution of executable or object code is made by offering -access to copy from a designated place, then offering equivalent -access to copy the source code from the same place counts as -distribution of the source code, even though third parties are not -compelled to copy the source along with the object code. - - 4. You may not copy, modify, sublicense, or distribute the Program -except as expressly provided under this License. Any attempt -otherwise to copy, modify, sublicense or distribute the Program is -void, and will automatically terminate your rights under this License. -However, parties who have received copies, or rights, from you under -this License will not have their licenses terminated so long as such -parties remain in full compliance. - - 5. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Program or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Program (or any work based on the -Program), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Program or works based on it. - - 6. Each time you redistribute the Program (or any work based on the -Program), the recipient automatically receives a license from the -original licensor to copy, distribute or modify the Program subject to -these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 7. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Program at all. For example, if a patent -license would not permit royalty-free redistribution of the Program by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Program. - -If any portion of this section is held invalid or unenforceable under -any particular circumstance, the balance of the section is intended to -apply and the section as a whole is intended to apply in other -circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system, which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 8. If the distribution and/or use of the Program is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Program under this License -may add an explicit geographical distribution limitation excluding -those countries, so that distribution is permitted only in or among -countries not thus excluded. In such case, this License incorporates -the limitation as if written in the body of this License. - - 9. The Free Software Foundation may publish revised and/or new versions -of the General Public License from time to time. Such new versions will -be similar in spirit to the present version, but may differ in detail to -address new problems or concerns. - -Each version is given a distinguishing version number. If the Program -specifies a version number of this License which applies to it and "any -later version", you have the option of following the terms and conditions -either of that version or of any later version published by the Free -Software Foundation. If the Program does not specify a version number of -this License, you may choose any version ever published by the Free Software -Foundation. - - 10. If you wish to incorporate parts of the Program into other free -programs whose distribution conditions are different, write to the author -to ask for permission. For software which is copyrighted by the Free -Software Foundation, write to the Free Software Foundation; we sometimes -make exceptions for this. Our decision will be guided by the two goals -of preserving the free status of all derivatives of our free software and -of promoting the sharing and reuse of software generally. - - NO WARRANTY - - 11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY -FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN -OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES -PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED -OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF -MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS -TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE -PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING, -REPAIR OR CORRECTION. - - 12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING -WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR -REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES, -INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING -OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED -TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY -YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER -PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE -POSSIBILITY OF SUCH DAMAGES. - - END OF TERMS AND CONDITIONS - - How to Apply These Terms to Your New Programs - - If you develop a new program, and you want it to be of the greatest -possible use to the public, the best way to achieve this is to make it -free software which everyone can redistribute and change under these terms. - - To do so, attach the following notices to the program. It is safest -to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least -the "copyright" line and a pointer to where the full notice is found. - - - Copyright (C) 19yy - - This program is free software; you can redistribute it and/or modify - it under the terms of the GNU General Public License as published by - the Free Software Foundation; either version 2 of the License, or - (at your option) any later version. - - This program is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the - GNU General Public License for more details. - - You should have received a copy of the GNU General Public License - along with this program; if not, write to the Free Software - Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -Also add information on how to contact you by electronic and paper mail. - -If the program is interactive, make it output a short notice like this -when it starts in an interactive mode: - - Gnomovision version 69, Copyright (C) 19yy name of author - Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'. - This is free software, and you are welcome to redistribute it - under certain conditions; type `show c' for details. - -The hypothetical commands `show w' and `show c' should show the appropriate -parts of the General Public License. Of course, the commands you use may -be called something other than `show w' and `show c'; they could even be -mouse-clicks or menu items--whatever suits your program. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the program, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the program - `Gnomovision' (which makes passes at compilers) written by James Hacker. - - , 1 April 1989 - Ty Coon, President of Vice - -This General Public License does not permit incorporating your program into -proprietary programs. If your program is a subroutine library, you may -consider it more useful to permit linking proprietary applications with the -library. If this is what you want to do, use the GNU Library General -Public License instead of this License. - ---------------------------------------------------------------------------- - - GNU LIBRARY GENERAL PUBLIC LICENSE - Version 2, June 1991 - - Copyright (C) 1991 Free Software Foundation, Inc. - 675 Mass Ave, Cambridge, MA 02139, USA - Everyone is permitted to copy and distribute verbatim copies - of this license document, but changing it is not allowed. - -[This is the first released version of the library GPL. It is - numbered 2 because it goes with version 2 of the ordinary GPL.] - - Preamble - - The licenses for most software are designed to take away your -freedom to share and change it. By contrast, the GNU General Public -Licenses are intended to guarantee your freedom to share and change -free software--to make sure the software is free for all its users. - - This license, the Library General Public License, applies to some -specially designated Free Software Foundation software, and to any -other libraries whose authors decide to use it. You can use it for -your libraries, too. - - When we speak of free software, we are referring to freedom, not -price. Our General Public Licenses are designed to make sure that you -have the freedom to distribute copies of free software (and charge for -this service if you wish), that you receive source code or can get it -if you want it, that you can change the software or use pieces of it -in new free programs; and that you know you can do these things. - - To protect your rights, we need to make restrictions that forbid -anyone to deny you these rights or to ask you to surrender the rights. -These restrictions translate to certain responsibilities for you if -you distribute copies of the library, or if you modify it. - - For example, if you distribute copies of the library, whether gratis -or for a fee, you must give the recipients all the rights that we gave -you. You must make sure that they, too, receive or can get the source -code. If you link a program with the library, you must provide -complete object files to the recipients so that they can relink them -with the library, after making changes to the library and recompiling -it. And you must show them these terms so they know their rights. - - Our method of protecting your rights has two steps: (1) copyright -the library, and (2) offer you this license which gives you legal -permission to copy, distribute and/or modify the library. - - Also, for each distributor's protection, we want to make certain -that everyone understands that there is no warranty for this free -library. If the library is modified by someone else and passed on, we -want its recipients to know that what they have is not the original -version, so that any problems introduced by others will not reflect on -the original authors' reputations. - - Finally, any free program is threatened constantly by software -patents. We wish to avoid the danger that companies distributing free -software will individually obtain patent licenses, thus in effect -transforming the program into proprietary software. To prevent this, -we have made it clear that any patent must be licensed for everyone's -free use or not licensed at all. - - Most GNU software, including some libraries, is covered by the ordinary -GNU General Public License, which was designed for utility programs. This -license, the GNU Library General Public License, applies to certain -designated libraries. This license is quite different from the ordinary -one; be sure to read it in full, and don't assume that anything in it is -the same as in the ordinary license. - - The reason we have a separate public license for some libraries is that -they blur the distinction we usually make between modifying or adding to a -program and simply using it. Linking a program with a library, without -changing the library, is in some sense simply using the library, and is -analogous to running a utility program or application program. However, in -a textual and legal sense, the linked executable is a combined work, a -derivative of the original library, and the ordinary General Public License -treats it as such. - - Because of this blurred distinction, using the ordinary General -Public License for libraries did not effectively promote software -sharing, because most developers did not use the libraries. We -concluded that weaker conditions might promote sharing better. - - However, unrestricted linking of non-free programs would deprive the -users of those programs of all benefit from the free status of the -libraries themselves. This Library General Public License is intended to -permit developers of non-free programs to use free libraries, while -preserving your freedom as a user of such programs to change the free -libraries that are incorporated in them. (We have not seen how to achieve -this as regards changes in header files, but we have achieved it as regards -changes in the actual functions of the Library.) The hope is that this -will lead to faster development of free libraries. - - The precise terms and conditions for copying, distribution and -modification follow. Pay close attention to the difference between a -"work based on the library" and a "work that uses the library". The -former contains code derived from the library, while the latter only -works together with the library. - - Note that it is possible for a library to be covered by the ordinary -General Public License rather than by this special one. - - GNU LIBRARY GENERAL PUBLIC LICENSE - TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION - - 0. This License Agreement applies to any software library which -contains a notice placed by the copyright holder or other authorized -party saying it may be distributed under the terms of this Library -General Public License (also called "this License"). Each licensee is -addressed as "you". - - A "library" means a collection of software functions and/or data -prepared so as to be conveniently linked with application programs -(which use some of those functions and data) to form executables. - - The "Library", below, refers to any such software library or work -which has been distributed under these terms. A "work based on the -Library" means either the Library or any derivative work under -copyright law: that is to say, a work containing the Library or a -portion of it, either verbatim or with modifications and/or translated -straightforwardly into another language. (Hereinafter, translation is -included without limitation in the term "modification".) - - "Source code" for a work means the preferred form of the work for -making modifications to it. For a library, complete source code means -all the source code for all modules it contains, plus any associated -interface definition files, plus the scripts used to control compilation -and installation of the library. - - Activities other than copying, distribution and modification are not -covered by this License; they are outside its scope. The act of -running a program using the Library is not restricted, and output from -such a program is covered only if its contents constitute a work based -on the Library (independent of the use of the Library in a tool for -writing it). Whether that is true depends on what the Library does -and what the program that uses the Library does. - - 1. You may copy and distribute verbatim copies of the Library's -complete source code as you receive it, in any medium, provided that -you conspicuously and appropriately publish on each copy an -appropriate copyright notice and disclaimer of warranty; keep intact -all the notices that refer to this License and to the absence of any -warranty; and distribute a copy of this License along with the -Library. - - You may charge a fee for the physical act of transferring a copy, -and you may at your option offer warranty protection in exchange for a -fee. - - 2. You may modify your copy or copies of the Library or any portion -of it, thus forming a work based on the Library, and copy and -distribute such modifications or work under the terms of Section 1 -above, provided that you also meet all of these conditions: - - a) The modified work must itself be a software library. - - b) You must cause the files modified to carry prominent notices - stating that you changed the files and the date of any change. - - c) You must cause the whole of the work to be licensed at no - charge to all third parties under the terms of this License. - - d) If a facility in the modified Library refers to a function or a - table of data to be supplied by an application program that uses - the facility, other than as an argument passed when the facility - is invoked, then you must make a good faith effort to ensure that, - in the event an application does not supply such function or - table, the facility still operates, and performs whatever part of - its purpose remains meaningful. - - (For example, a function in a library to compute square roots has - a purpose that is entirely well-defined independent of the - application. Therefore, Subsection 2d requires that any - application-supplied function or table used by this function must - be optional: if the application does not supply it, the square - root function must still compute square roots.) - -These requirements apply to the modified work as a whole. If -identifiable sections of that work are not derived from the Library, -and can be reasonably considered independent and separate works in -themselves, then this License, and its terms, do not apply to those -sections when you distribute them as separate works. But when you -distribute the same sections as part of a whole which is a work based -on the Library, the distribution of the whole must be on the terms of -this License, whose permissions for other licensees extend to the -entire whole, and thus to each and every part regardless of who wrote -it. - -Thus, it is not the intent of this section to claim rights or contest -your rights to work written entirely by you; rather, the intent is to -exercise the right to control the distribution of derivative or -collective works based on the Library. - -In addition, mere aggregation of another work not based on the Library -with the Library (or with a work based on the Library) on a volume of -a storage or distribution medium does not bring the other work under -the scope of this License. - - 3. You may opt to apply the terms of the ordinary GNU General Public -License instead of this License to a given copy of the Library. To do -this, you must alter all the notices that refer to this License, so -that they refer to the ordinary GNU General Public License, version 2, -instead of to this License. (If a newer version than version 2 of the -ordinary GNU General Public License has appeared, then you can specify -that version instead if you wish.) Do not make any other change in -these notices. - - Once this change is made in a given copy, it is irreversible for -that copy, so the ordinary GNU General Public License applies to all -subsequent copies and derivative works made from that copy. - - This option is useful when you wish to copy part of the code of -the Library into a program that is not a library. - - 4. You may copy and distribute the Library (or a portion or -derivative of it, under Section 2) in object code or executable form -under the terms of Sections 1 and 2 above provided that you accompany -it with the complete corresponding machine-readable source code, which -must be distributed under the terms of Sections 1 and 2 above on a -medium customarily used for software interchange. - - If distribution of object code is made by offering access to copy -from a designated place, then offering equivalent access to copy the -source code from the same place satisfies the requirement to -distribute the source code, even though third parties are not -compelled to copy the source along with the object code. - - 5. A program that contains no derivative of any portion of the -Library, but is designed to work with the Library by being compiled or -linked with it, is called a "work that uses the Library". Such a -work, in isolation, is not a derivative work of the Library, and -therefore falls outside the scope of this License. - - However, linking a "work that uses the Library" with the Library -creates an executable that is a derivative of the Library (because it -contains portions of the Library), rather than a "work that uses the -library". The executable is therefore covered by this License. -Section 6 states terms for distribution of such executables. - - When a "work that uses the Library" uses material from a header file -that is part of the Library, the object code for the work may be a -derivative work of the Library even though the source code is not. -Whether this is true is especially significant if the work can be -linked without the Library, or if the work is itself a library. The -threshold for this to be true is not precisely defined by law. - - If such an object file uses only numerical parameters, data -structure layouts and accessors, and small macros and small inline -functions (ten lines or less in length), then the use of the object -file is unrestricted, regardless of whether it is legally a derivative -work. (Executables containing this object code plus portions of the -Library will still fall under Section 6.) - - Otherwise, if the work is a derivative of the Library, you may -distribute the object code for the work under the terms of Section 6. -Any executables containing that work also fall under Section 6, -whether or not they are linked directly with the Library itself. - - 6. As an exception to the Sections above, you may also compile or -link a "work that uses the Library" with the Library to produce a -work containing portions of the Library, and distribute that work -under terms of your choice, provided that the terms permit -modification of the work for the customer's own use and reverse -engineering for debugging such modifications. - - You must give prominent notice with each copy of the work that the -Library is used in it and that the Library and its use are covered by -this License. You must supply a copy of this License. If the work -during execution displays copyright notices, you must include the -copyright notice for the Library among them, as well as a reference -directing the user to the copy of this License. Also, you must do one -of these things: - - a) Accompany the work with the complete corresponding - machine-readable source code for the Library including whatever - changes were used in the work (which must be distributed under - Sections 1 and 2 above); and, if the work is an executable linked - with the Library, with the complete machine-readable "work that - uses the Library", as object code and/or source code, so that the - user can modify the Library and then relink to produce a modified - executable containing the modified Library. (It is understood - that the user who changes the contents of definitions files in the - Library will not necessarily be able to recompile the application - to use the modified definitions.) - - b) Accompany the work with a written offer, valid for at - least three years, to give the same user the materials - specified in Subsection 6a, above, for a charge no more - than the cost of performing this distribution. - - c) If distribution of the work is made by offering access to copy - from a designated place, offer equivalent access to copy the above - specified materials from the same place. - - d) Verify that the user has already received a copy of these - materials or that you have already sent this user a copy. - - For an executable, the required form of the "work that uses the -Library" must include any data and utility programs needed for -reproducing the executable from it. However, as a special exception, -the source code distributed need not include anything that is normally -distributed (in either source or binary form) with the major -components (compiler, kernel, and so on) of the operating system on -which the executable runs, unless that component itself accompanies -the executable. - - It may happen that this requirement contradicts the license -restrictions of other proprietary libraries that do not normally -accompany the operating system. Such a contradiction means you cannot -use both them and the Library together in an executable that you -distribute. - - 7. You may place library facilities that are a work based on the -Library side-by-side in a single library together with other library -facilities not covered by this License, and distribute such a combined -library, provided that the separate distribution of the work based on -the Library and of the other library facilities is otherwise -permitted, and provided that you do these two things: - - a) Accompany the combined library with a copy of the same work - based on the Library, uncombined with any other library - facilities. This must be distributed under the terms of the - Sections above. - - b) Give prominent notice with the combined library of the fact - that part of it is a work based on the Library, and explaining - where to find the accompanying uncombined form of the same work. - - 8. You may not copy, modify, sublicense, link with, or distribute -the Library except as expressly provided under this License. Any -attempt otherwise to copy, modify, sublicense, link with, or -distribute the Library is void, and will automatically terminate your -rights under this License. However, parties who have received copies, -or rights, from you under this License will not have their licenses -terminated so long as such parties remain in full compliance. - - 9. You are not required to accept this License, since you have not -signed it. However, nothing else grants you permission to modify or -distribute the Library or its derivative works. These actions are -prohibited by law if you do not accept this License. Therefore, by -modifying or distributing the Library (or any work based on the -Library), you indicate your acceptance of this License to do so, and -all its terms and conditions for copying, distributing or modifying -the Library or works based on it. - - 10. Each time you redistribute the Library (or any work based on the -Library), the recipient automatically receives a license from the -original licensor to copy, distribute, link with or modify the Library -subject to these terms and conditions. You may not impose any further -restrictions on the recipients' exercise of the rights granted herein. -You are not responsible for enforcing compliance by third parties to -this License. - - 11. If, as a consequence of a court judgment or allegation of patent -infringement or for any other reason (not limited to patent issues), -conditions are imposed on you (whether by court order, agreement or -otherwise) that contradict the conditions of this License, they do not -excuse you from the conditions of this License. If you cannot -distribute so as to satisfy simultaneously your obligations under this -License and any other pertinent obligations, then as a consequence you -may not distribute the Library at all. For example, if a patent -license would not permit royalty-free redistribution of the Library by -all those who receive copies directly or indirectly through you, then -the only way you could satisfy both it and this License would be to -refrain entirely from distribution of the Library. - -If any portion of this section is held invalid or unenforceable under any -particular circumstance, the balance of the section is intended to apply, -and the section as a whole is intended to apply in other circumstances. - -It is not the purpose of this section to induce you to infringe any -patents or other property right claims or to contest validity of any -such claims; this section has the sole purpose of protecting the -integrity of the free software distribution system which is -implemented by public license practices. Many people have made -generous contributions to the wide range of software distributed -through that system in reliance on consistent application of that -system; it is up to the author/donor to decide if he or she is willing -to distribute software through any other system and a licensee cannot -impose that choice. - -This section is intended to make thoroughly clear what is believed to -be a consequence of the rest of this License. - - 12. If the distribution and/or use of the Library is restricted in -certain countries either by patents or by copyrighted interfaces, the -original copyright holder who places the Library under this License may add -an explicit geographical distribution limitation excluding those countries, -so that distribution is permitted only in or among countries not thus -excluded. In such case, this License incorporates the limitation as if -written in the body of this License. - - 13. The Free Software Foundation may publish revised and/or new -versions of the Library General Public License from time to time. -Such new versions will be similar in spirit to the present version, -but may differ in detail to address new problems or concerns. - -Each version is given a distinguishing version number. If the Library -specifies a version number of this License which applies to it and -"any later version", you have the option of following the terms and -conditions either of that version or of any later version published by -the Free Software Foundation. If the Library does not specify a -license version number, you may choose any version ever published by -the Free Software Foundation. - - 14. If you wish to incorporate parts of the Library into other free -programs whose distribution conditions are incompatible with these, -write to the author to ask for permission. For software which is -copyrighted by the Free Software Foundation, write to the Free -Software Foundation; we sometimes make exceptions for this. Our -decision will be guided by the two goals of preserving the free status -of all derivatives of our free software and of promoting the sharing -and reuse of software generally. - - NO WARRANTY - - 15. BECAUSE THE LIBRARY IS LICENSED FREE OF CHARGE, THERE IS NO -WARRANTY FOR THE LIBRARY, TO THE EXTENT PERMITTED BY APPLICABLE LAW. -EXCEPT WHEN OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR -OTHER PARTIES PROVIDE THE LIBRARY "AS IS" WITHOUT WARRANTY OF ANY -KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE -IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR -PURPOSE. THE ENTIRE RISK AS TO THE QUALITY AND PERFORMANCE OF THE -LIBRARY IS WITH YOU. SHOULD THE LIBRARY PROVE DEFECTIVE, YOU ASSUME -THE COST OF ALL NECESSARY SERVICING, REPAIR OR CORRECTION. - - 16. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN -WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY -AND/OR REDISTRIBUTE THE LIBRARY AS PERMITTED ABOVE, BE LIABLE TO YOU -FOR DAMAGES, INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR -CONSEQUENTIAL DAMAGES ARISING OUT OF THE USE OR INABILITY TO USE THE -LIBRARY (INCLUDING BUT NOT LIMITED TO LOSS OF DATA OR DATA BEING -RENDERED INACCURATE OR LOSSES SUSTAINED BY YOU OR THIRD PARTIES OR A -FAILURE OF THE LIBRARY TO OPERATE WITH ANY OTHER SOFTWARE), EVEN IF -SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE POSSIBILITY OF SUCH -DAMAGES. - - END OF TERMS AND CONDITIONS - - Appendix: How to Apply These Terms to Your New Libraries - - If you develop a new library, and you want it to be of the greatest -possible use to the public, we recommend making it free software that -everyone can redistribute and change. You can do so by permitting -redistribution under these terms (or, alternatively, under the terms of the -ordinary General Public License). - - To apply these terms, attach the following notices to the library. It is -safest to attach them to the start of each source file to most effectively -convey the exclusion of warranty; and each file should have at least the -"copyright" line and a pointer to where the full notice is found. - - - Copyright (C) - - This library is free software; you can redistribute it and/or - modify it under the terms of the GNU Library General Public - License as published by the Free Software Foundation; either - version 2 of the License, or (at your option) any later version. - - This library is distributed in the hope that it will be useful, - but WITHOUT ANY WARRANTY; without even the implied warranty of - MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - Library General Public License for more details. - - You should have received a copy of the GNU Library General Public - License along with this library; if not, write to the Free - Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA. - -Also add information on how to contact you by electronic and paper mail. - -You should also get your employer (if you work as a programmer) or your -school, if any, to sign a "copyright disclaimer" for the library, if -necessary. Here is a sample; alter the names: - - Yoyodyne, Inc., hereby disclaims all copyright interest in the - library `Frob' (a library for tweaking knobs) written by James Random Hacker. - - , 1 April 1990 - Ty Coon, President of Vice - -That's all there is to it! diff --git a/rpmio/rpmpgp_legacy/README b/rpmio/rpmpgp_legacy/README deleted file mode 100644 index 0008f3729a..0000000000 --- a/rpmio/rpmpgp_legacy/README +++ /dev/null @@ -1,15 +0,0 @@ - -This is the former internal RPM OpenPGP parser, decommissioned -after twenty years of service. - -This parser is considered insecure: it simply ignores various critical -aspects of OpenPGP, such as sub-packet binding signatures and takes -various other questionable shortcuts. - -This is not a standalone project, it can only be built as a part of RPM. -To build, check this repository into the rpmio/ directory of RPM's -sources and re-run cmake with `-DWITH_SEQUOIA=OFF -DWITH_LEGACY_OPENPGP=ON` - -Use entirely at your own risk, the RPM project does not provide support -for this parser. - diff --git a/rpmio/rpmpgp_legacy/digest_libgcrypt.c b/rpmio/rpmpgp_legacy/digest_libgcrypt.c deleted file mode 100644 index 7186d181de..0000000000 --- a/rpmio/rpmpgp_legacy/digest_libgcrypt.c +++ /dev/null @@ -1,445 +0,0 @@ -#include "system.h" - -#include - -#include -#include "rpmpgp_internal.h" -#include "debug.h" - -static int hashalgo2gcryalgo(int hashalgo) -{ - switch (hashalgo) { - case RPM_HASH_MD5: - return GCRY_MD_MD5; - case RPM_HASH_SHA1: - return GCRY_MD_SHA1; - case RPM_HASH_SHA224: - return GCRY_MD_SHA224; - case RPM_HASH_SHA256: - return GCRY_MD_SHA256; - case RPM_HASH_SHA384: - return GCRY_MD_SHA384; - case RPM_HASH_SHA512: - return GCRY_MD_SHA512; - default: - return 0; - } -} - -/****************************** RSA **************************************/ - -struct pgpDigSigRSA_s { - gcry_mpi_t s; -}; - -struct pgpDigKeyRSA_s { - gcry_mpi_t n; - gcry_mpi_t e; -}; - -static int pgpSetSigMpiRSA(pgpDigAlg pgpsig, int num, const uint8_t *p) -{ - struct pgpDigSigRSA_s *sig = pgpsig->data; - int mlen = pgpMpiLen(p); - int rc = 1; - - if (!sig) - sig = pgpsig->data = xcalloc(1, sizeof(*sig)); - - switch (num) { - case 0: - if (!gcry_mpi_scan(&sig->s, GCRYMPI_FMT_PGP, p, mlen, NULL)) - rc = 0; - break; - } - return rc; -} - -static int pgpSetKeyMpiRSA(pgpDigAlg pgpkey, int num, const uint8_t *p) -{ - struct pgpDigKeyRSA_s *key = pgpkey->data; - int mlen = pgpMpiLen(p); - int rc = 1; - - if (!key) - key = pgpkey->data = xcalloc(1, sizeof(*key)); - - switch (num) { - case 0: - if (!gcry_mpi_scan(&key->n, GCRYMPI_FMT_PGP, p, mlen, NULL)) - rc = 0; - break; - case 1: - if (!gcry_mpi_scan(&key->e, GCRYMPI_FMT_PGP, p, mlen, NULL)) - rc = 0; - break; - } - return rc; -} - -static int pgpVerifySigRSA(pgpDigAlg pgpkey, pgpDigAlg pgpsig, uint8_t *hash, size_t hashlen, int hash_algo) -{ - struct pgpDigKeyRSA_s *key = pgpkey->data; - struct pgpDigSigRSA_s *sig = pgpsig->data; - gcry_sexp_t sexp_sig = NULL, sexp_data = NULL, sexp_pkey = NULL; - const char *hash_algo_name; - int rc = 1; - - if (!sig || !key) - return rc; - - hash_algo_name = gcry_md_algo_name(hashalgo2gcryalgo(hash_algo)); - gcry_sexp_build(&sexp_sig, NULL, "(sig-val (rsa (s %M)))", sig->s); - gcry_sexp_build(&sexp_data, NULL, "(data (flags pkcs1) (hash %s %b))", hash_algo_name, (int)hashlen, (const char *)hash); - gcry_sexp_build(&sexp_pkey, NULL, "(public-key (rsa (n %M) (e %M)))", key->n, key->e); - if (sexp_sig && sexp_data && sexp_pkey) - rc = gcry_pk_verify(sexp_sig, sexp_data, sexp_pkey) == 0 ? 0 : 1; - gcry_sexp_release(sexp_sig); - gcry_sexp_release(sexp_data); - gcry_sexp_release(sexp_pkey); - return rc; -} - -static void pgpFreeSigRSA(pgpDigAlg pgpsig) -{ - struct pgpDigSigRSA_s *sig = pgpsig->data; - if (sig) { - gcry_mpi_release(sig->s); - pgpsig->data = _free(sig); - } -} - -static void pgpFreeKeyRSA(pgpDigAlg pgpkey) -{ - struct pgpDigKeyRSA_s *key = pgpkey->data; - if (key) { - gcry_mpi_release(key->n); - gcry_mpi_release(key->e); - pgpkey->data = _free(key); - } -} - - -/****************************** DSA **************************************/ - -struct pgpDigSigDSA_s { - gcry_mpi_t r; - gcry_mpi_t s; -}; - -struct pgpDigKeyDSA_s { - gcry_mpi_t p; - gcry_mpi_t q; - gcry_mpi_t g; - gcry_mpi_t y; -}; - -static int pgpSetSigMpiDSA(pgpDigAlg pgpsig, int num, const uint8_t *p) -{ - struct pgpDigSigDSA_s *sig = pgpsig->data; - int mlen = pgpMpiLen(p); - int rc = 1; - - if (!sig) - sig = pgpsig->data = xcalloc(1, sizeof(*sig)); - - switch (num) { - case 0: - if (!gcry_mpi_scan(&sig->r, GCRYMPI_FMT_PGP, p, mlen, NULL)) - rc = 0; - break; - case 1: - if (!gcry_mpi_scan(&sig->s, GCRYMPI_FMT_PGP, p, mlen, NULL)) - rc = 0; - break; - } - return rc; -} - -static int pgpSetKeyMpiDSA(pgpDigAlg pgpkey, int num, const uint8_t *p) -{ - struct pgpDigKeyDSA_s *key = pgpkey->data; - int mlen = pgpMpiLen(p); - int rc = 1; - - if (!key) - key = pgpkey->data = xcalloc(1, sizeof(*key)); - - switch (num) { - case 0: - if (!gcry_mpi_scan(&key->p, GCRYMPI_FMT_PGP, p, mlen, NULL)) - rc = 0; - break; - case 1: - if (!gcry_mpi_scan(&key->q, GCRYMPI_FMT_PGP, p, mlen, NULL)) - rc = 0; - break; - case 2: - if (!gcry_mpi_scan(&key->g, GCRYMPI_FMT_PGP, p, mlen, NULL)) - rc = 0; - break; - case 3: - if (!gcry_mpi_scan(&key->y, GCRYMPI_FMT_PGP, p, mlen, NULL)) - rc = 0; - break; - } - return rc; -} - -static int pgpVerifySigDSA(pgpDigAlg pgpkey, pgpDigAlg pgpsig, uint8_t *hash, size_t hashlen, int hash_algo) -{ - struct pgpDigKeyDSA_s *key = pgpkey->data; - struct pgpDigSigDSA_s *sig = pgpsig->data; - gcry_sexp_t sexp_sig = NULL, sexp_data = NULL, sexp_pkey = NULL; - int rc = 1; - size_t qlen; - - if (!sig || !key) - return rc; - - qlen = (mpi_get_nbits(key->q) + 7) / 8; - if (qlen < 20) - qlen = 20; /* sanity */ - if (hashlen > qlen) - hashlen = qlen; /* dsa2: truncate hash to qlen */ - gcry_sexp_build(&sexp_sig, NULL, "(sig-val (dsa (r %M) (s %M)))", sig->r, sig->s); - gcry_sexp_build(&sexp_data, NULL, "(data (flags raw) (value %b))", (int)hashlen, (const char *)hash); - gcry_sexp_build(&sexp_pkey, NULL, "(public-key (dsa (p %M) (q %M) (g %M) (y %M)))", key->p, key->q, key->g, key->y); - if (sexp_sig && sexp_data && sexp_pkey) - rc = gcry_pk_verify(sexp_sig, sexp_data, sexp_pkey) == 0 ? 0 : 1; - gcry_sexp_release(sexp_sig); - gcry_sexp_release(sexp_data); - gcry_sexp_release(sexp_pkey); - return rc; -} - -static void pgpFreeSigDSA(pgpDigAlg pgpsig) -{ - struct pgpDigSigDSA_s *sig = pgpsig->data; - if (sig) { - gcry_mpi_release(sig->r); - gcry_mpi_release(sig->s); - pgpsig->data = _free(sig); - } -} - -static void pgpFreeKeyDSA(pgpDigAlg pgpkey) -{ - struct pgpDigKeyDSA_s *key = pgpkey->data; - if (key) { - gcry_mpi_release(key->p); - gcry_mpi_release(key->q); - gcry_mpi_release(key->g); - gcry_mpi_release(key->y); - pgpkey->data = _free(key); - } -} - - -/****************************** EDDSA **************************************/ - -struct pgpDigSigEDDSA_s { - gcry_mpi_t r; - gcry_mpi_t s; -}; - -struct pgpDigKeyEDDSA_s { - gcry_mpi_t q; -}; - -static int pgpSetSigMpiEDDSA(pgpDigAlg pgpsig, int num, const uint8_t *p) -{ - struct pgpDigSigEDDSA_s *sig = pgpsig->data; - int mlen = pgpMpiLen(p); - int rc = 1; - - if (!sig) - sig = pgpsig->data = xcalloc(1, sizeof(*sig)); - - switch (num) { - case 0: - if (!gcry_mpi_scan(&sig->r, GCRYMPI_FMT_PGP, p, mlen, NULL)) - rc = 0; - break; - case 1: - if (!gcry_mpi_scan(&sig->s, GCRYMPI_FMT_PGP, p, mlen, NULL)) - rc = 0; - break; - } - return rc; -} - -static int pgpSetKeyMpiEDDSA(pgpDigAlg pgpkey, int num, const uint8_t *p) -{ - struct pgpDigKeyEDDSA_s *key = pgpkey->data; - int mlen = pgpMpiLen(p); - int rc = 1; - - if (!key) - key = pgpkey->data = xcalloc(1, sizeof(*key)); - - switch (num) { - case 0: - if (!gcry_mpi_scan(&key->q, GCRYMPI_FMT_PGP, p, mlen, NULL)) - rc = 0; - break; - } - return rc; -} - -static int -ed25519_zero_extend(gcry_mpi_t x, unsigned char *buf, int bufl) -{ - int n = (gcry_mpi_get_nbits(x) + 7) / 8; - if (n == 0 || n > bufl) - return 1; - n = bufl - n; - if (n) - memset(buf, 0, n); - gcry_mpi_print(GCRYMPI_FMT_USG, buf + n, bufl - n, NULL, x); - return 0; -} - -static int pgpVerifySigEDDSA(pgpDigAlg pgpkey, pgpDigAlg pgpsig, uint8_t *hash, size_t hashlen, int hash_algo) -{ - struct pgpDigKeyEDDSA_s *key = pgpkey->data; - struct pgpDigSigEDDSA_s *sig = pgpsig->data; - gcry_sexp_t sexp_sig = NULL, sexp_data = NULL, sexp_pkey = NULL; - int rc = 1; - unsigned char buf_r[32], buf_s[32]; - - if (!sig || !key) - return rc; - if (pgpkey->curve != PGPCURVE_ED25519) - return rc; - if (ed25519_zero_extend(sig->r, buf_r, 32) || ed25519_zero_extend(sig->s, buf_s, 32)) - return rc; - gcry_sexp_build(&sexp_sig, NULL, "(sig-val (eddsa (r %b) (s %b)))", 32, (const char *)buf_r, 32, (const char *)buf_s, 32); - gcry_sexp_build(&sexp_data, NULL, "(data (flags eddsa) (hash-algo sha512) (value %b))", (int)hashlen, (const char *)hash); - gcry_sexp_build(&sexp_pkey, NULL, "(public-key (ecc (curve \"Ed25519\") (flags eddsa) (q %M)))", key->q); - if (sexp_sig && sexp_data && sexp_pkey) - rc = gcry_pk_verify(sexp_sig, sexp_data, sexp_pkey) == 0 ? 0 : 1; - gcry_sexp_release(sexp_sig); - gcry_sexp_release(sexp_data); - gcry_sexp_release(sexp_pkey); - return rc; -} - -static void pgpFreeSigEDDSA(pgpDigAlg pgpsig) -{ - struct pgpDigSigEDDSA_s *sig = pgpsig->data; - if (sig) { - gcry_mpi_release(sig->r); - gcry_mpi_release(sig->s); - pgpsig->data = _free(sig); - } -} - -static void pgpFreeKeyEDDSA(pgpDigAlg pgpkey) -{ - struct pgpDigKeyEDDSA_s *key = pgpkey->data; - if (key) { - gcry_mpi_release(key->q); - pgpkey->data = _free(key); - } -} - - -/****************************** NULL **************************************/ - -static int pgpSetMpiNULL(pgpDigAlg pgpkey, int num, const uint8_t *p) -{ - return 1; -} - -static int pgpVerifyNULL(pgpDigAlg pgpkey, pgpDigAlg pgpsig, - uint8_t *hash, size_t hashlen, int hash_algo) -{ - return 1; -} - -static int pgpSupportedCurve(int curve) -{ - if (curve == PGPCURVE_ED25519) { - static int supported_ed25519; - if (!supported_ed25519) { - gcry_sexp_t sexp = NULL; - unsigned int nbits; - gcry_sexp_build(&sexp, NULL, "(public-key (ecc (curve \"Ed25519\")))"); - nbits = gcry_pk_get_nbits(sexp); - gcry_sexp_release(sexp); - supported_ed25519 = nbits > 0 ? 1 : -1; - } - return supported_ed25519 > 0; - } - return 0; -} - -pgpDigAlg pgpPubkeyNew(int algo, int curve) -{ - pgpDigAlg ka = xcalloc(1, sizeof(*ka));; - - switch (algo) { - case PGPPUBKEYALGO_RSA: - ka->setmpi = pgpSetKeyMpiRSA; - ka->free = pgpFreeKeyRSA; - ka->mpis = 2; - break; - case PGPPUBKEYALGO_DSA: - ka->setmpi = pgpSetKeyMpiDSA; - ka->free = pgpFreeKeyDSA; - ka->mpis = 4; - break; - case PGPPUBKEYALGO_EDDSA: - if (!pgpSupportedCurve(curve)) { - ka->setmpi = pgpSetMpiNULL; - ka->mpis = -1; - break; - } - ka->setmpi = pgpSetKeyMpiEDDSA; - ka->free = pgpFreeKeyEDDSA; - ka->mpis = 1; - ka->curve = curve; - break; - default: - ka->setmpi = pgpSetMpiNULL; - ka->mpis = -1; - break; - } - - ka->verify = pgpVerifyNULL; /* keys can't be verified */ - - return ka; -} - -pgpDigAlg pgpSignatureNew(int algo) -{ - pgpDigAlg sa = xcalloc(1, sizeof(*sa)); - - switch (algo) { - case PGPPUBKEYALGO_RSA: - sa->setmpi = pgpSetSigMpiRSA; - sa->free = pgpFreeSigRSA; - sa->verify = pgpVerifySigRSA; - sa->mpis = 1; - break; - case PGPPUBKEYALGO_DSA: - sa->setmpi = pgpSetSigMpiDSA; - sa->free = pgpFreeSigDSA; - sa->verify = pgpVerifySigDSA; - sa->mpis = 2; - break; - case PGPPUBKEYALGO_EDDSA: - sa->setmpi = pgpSetSigMpiEDDSA; - sa->free = pgpFreeSigEDDSA; - sa->verify = pgpVerifySigEDDSA; - sa->mpis = 2; - break; - default: - sa->setmpi = pgpSetMpiNULL; - sa->verify = pgpVerifyNULL; - sa->mpis = -1; - break; - } - return sa; -} diff --git a/rpmio/rpmpgp_legacy/digest_openssl.c b/rpmio/rpmpgp_legacy/digest_openssl.c deleted file mode 100644 index 4350ffcca2..0000000000 --- a/rpmio/rpmpgp_legacy/digest_openssl.c +++ /dev/null @@ -1,691 +0,0 @@ -#include "system.h" - -#include -#include -#include -#include -#include -#include - -#include "rpmpgp_internal.h" - -static const EVP_MD *getEVPMD(int hashalgo) -{ - switch (hashalgo) { - - case RPM_HASH_MD5: - return EVP_md5(); - - case RPM_HASH_SHA1: - return EVP_sha1(); - - case RPM_HASH_SHA256: - return EVP_sha256(); - - case RPM_HASH_SHA384: - return EVP_sha384(); - - case RPM_HASH_SHA512: - return EVP_sha512(); - - case RPM_HASH_SHA224: - return EVP_sha224(); - - default: - return EVP_md_null(); - } -} -/****************************** RSA **************************************/ - -/* Key */ - -struct pgpDigKeyRSA_s { - size_t nbytes; /* Size of modulus */ - - BIGNUM *n; /* Common Modulus */ - BIGNUM *e; /* Public Exponent */ - EVP_PKEY *evp_pkey; /* Fully constructed key */ - unsigned char immutable; /* if set, this key cannot be mutated */ -}; - -static int constructRSASigningKey(struct pgpDigKeyRSA_s *key) -{ - EVP_PKEY_CTX *ctx = NULL; - OSSL_PARAM_BLD *param_bld = NULL; - OSSL_PARAM *params =NULL; - - if (key->evp_pkey) { - /* We've already constructed it, so just reuse it */ - return 1; - } else if (key->immutable) - return 0; - key->immutable = 1; - - ctx = EVP_PKEY_CTX_new_from_name(NULL, "RSA", NULL); - if (!ctx) - goto exit; - param_bld = OSSL_PARAM_BLD_new(); - if (!param_bld) - goto exit; - if (!OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_RSA_N, key->n)) - goto exit; - if (!OSSL_PARAM_BLD_push_BN(param_bld, OSSL_PKEY_PARAM_RSA_E, key->e)) - goto exit; - params = OSSL_PARAM_BLD_to_param(param_bld); - if (!params) - goto exit; - - if (!EVP_PKEY_fromdata_init(ctx)) - goto exit; - if (!EVP_PKEY_fromdata(ctx, &key->evp_pkey, EVP_PKEY_PUBLIC_KEY, params)) - goto exit; - EVP_PKEY_CTX_free(ctx); - key->n = key->e = NULL; - - return 1; - - exit: - EVP_PKEY_CTX_free(ctx); - OSSL_PARAM_BLD_free(param_bld); - OSSL_PARAM_free(params); - - return 0; -} - -static int pgpSetKeyMpiRSA(pgpDigAlg pgpkey, int num, const uint8_t *p) -{ - size_t mlen = pgpMpiLen(p) - 2; - struct pgpDigKeyRSA_s *key = pgpkey->data; - - if (!key) - key = pgpkey->data = xcalloc(1, sizeof(*key)); - else if (key->immutable) - return 1; - - switch (num) { - case 0: - /* Modulus */ - if (key->n) { - /* This should only ever happen once per key */ - return 1; - } - - key->nbytes = mlen; - /* Create a BIGNUM from the pointer. - Note: this assumes big-endian data as required by PGP */ - key->n = BN_bin2bn(p+2, mlen, NULL); - if (!key->n) return 1; - break; - - case 1: - /* Exponent */ - if (key->e) { - /* This should only ever happen once per key */ - return 1; - } - - /* Create a BIGNUM from the pointer. - Note: this assumes big-endian data as required by PGP */ - key->e = BN_bin2bn(p+2, mlen, NULL); - if (!key->e) return 1; - break; - } - - return 0; -} - -static void pgpFreeKeyRSA(pgpDigAlg pgpkey) -{ - struct pgpDigKeyRSA_s *key = pgpkey->data; - if (key) { - if (key->evp_pkey) { - EVP_PKEY_free(key->evp_pkey); - } else { - /* If key->evp_pkey was constructed, - * the memory management of these BNs - * are freed with it. */ - BN_clear_free(key->n); - BN_clear_free(key->e); - } - - free(key); - } -} - -/* Signature */ - -struct pgpDigSigRSA_s { - BIGNUM *bn; - size_t len; -}; - -static int pgpSetSigMpiRSA(pgpDigAlg pgpsig, int num, const uint8_t *p) -{ - BIGNUM *bn = NULL; - - int mlen = pgpMpiLen(p) - 2; - int rc = 1; - - struct pgpDigSigRSA_s *sig = pgpsig->data; - if (!sig) { - sig = xcalloc(1, sizeof(*sig)); - } - - switch (num) { - case 0: - if (sig->bn) { - /* This should only ever happen once per signature */ - return 1; - } - - bn = sig->bn = BN_new(); - if (!bn) return 1; - - /* Create a BIGNUM from the signature pointer. - Note: this assumes big-endian data as required - by the PGP multiprecision integer format - (RFC4880, Section 3.2) - This will be useful later, as we can - retrieve this value with appropriate - padding. */ - bn = BN_bin2bn(p+2, mlen, bn); - if (!bn) return 1; - - sig->bn = bn; - sig->len = mlen; - - pgpsig->data = sig; - rc = 0; - break; - } - return rc; -} - -static void pgpFreeSigRSA(pgpDigAlg pgpsig) -{ - struct pgpDigSigRSA_s *sig = pgpsig->data; - if (sig) { - BN_clear_free(sig->bn); - free(pgpsig->data); - } -} - -static int pgpVerifySigRSA(pgpDigAlg pgpkey, pgpDigAlg pgpsig, - uint8_t *hash, size_t hashlen, int hash_algo) -{ - int rc = 1; /* assume failure */ - EVP_PKEY_CTX *pkey_ctx = NULL; - struct pgpDigSigRSA_s *sig = pgpsig->data; - - void *padded_sig = NULL; - - struct pgpDigKeyRSA_s *key = pgpkey->data; - - if (!constructRSASigningKey(key)) - goto done; - - pkey_ctx = EVP_PKEY_CTX_new(key->evp_pkey, NULL); - if (!pkey_ctx) - goto done; - - if (EVP_PKEY_verify_init(pkey_ctx) != 1) - goto done; - - if (EVP_PKEY_CTX_set_rsa_padding(pkey_ctx, RSA_PKCS1_PADDING) <= 0) - goto done; - - if (EVP_PKEY_CTX_set_signature_md(pkey_ctx, getEVPMD(hash_algo)) <= 0) - goto done; - - int pkey_len = EVP_PKEY_size(key->evp_pkey); - padded_sig = xcalloc(1, pkey_len); - if (BN_bn2binpad(sig->bn, padded_sig, pkey_len) <= 0) - goto done; - - if (EVP_PKEY_verify(pkey_ctx, padded_sig, pkey_len, hash, hashlen) == 1) - { - /* Success */ - rc = 0; - } - -done: - EVP_PKEY_CTX_free(pkey_ctx); - free(padded_sig); - return rc; -} - -/****************************** DSA ***************************************/ -/* Key */ - -struct pgpDigKeyDSA_s { - BIGNUM *p; /* Prime */ - BIGNUM *q; /* Subprime */ - BIGNUM *g; /* Base */ - BIGNUM *y; /* Public Key */ - EVP_PKEY *evp_pkey; /* Fully constructed key */ -}; - -static int constructDSASigningKey(struct pgpDigKeyDSA_s *key) -{ - int rc; - - if (key->evp_pkey) { - /* We've already constructed it, so just reuse it */ - return 1; - } - - EVP_PKEY_CTX *ctx = EVP_PKEY_CTX_new_from_name(NULL, "DSA", NULL); - OSSL_PARAM params[5] = { - OSSL_PARAM_BN("pbits", key->p, BN_num_bytes(key->p)*8), - OSSL_PARAM_BN("qbits", key->q, BN_num_bytes(key->q)*8), - OSSL_PARAM_BN("gindex", key->g, BN_num_bytes(key->g)*8), - OSSL_PARAM_utf8_string("digest", "SHA384", 0), - OSSL_PARAM_END, - }; - EVP_PKEY_CTX_set_params(ctx, params); - EVP_PKEY_fromdata(ctx, &key->evp_pkey, EVP_PKEY_PUBLIC_KEY, params); - rc = 1; - return rc; -} - - -static int pgpSetKeyMpiDSA(pgpDigAlg pgpkey, int num, const uint8_t *p) -{ - BIGNUM *bn; - size_t mlen = pgpMpiLen(p) - 2; - struct pgpDigKeyDSA_s *key = pgpkey->data; - - if (!key) { - key = pgpkey->data = xcalloc(1, sizeof(*key)); - } - - /* Create a BIGNUM from the key pointer. - Note: this assumes big-endian data as required - by the PGP multiprecision integer format - (RFC4880, Section 3.2) */ - bn = BN_bin2bn(p+2, mlen, NULL); - if (!bn) return 1; - - switch (num) { - case 0: - /* Prime */ - if (key->p) { - /* This should only ever happen once per key */ - return 1; - } - key->p = bn; - break; - - case 1: - /* Subprime */ - if (key->q) { - /* This should only ever happen once per key */ - return 1; - } - key->q = bn; - break; - case 2: - /* Base */ - if (key->g) { - /* This should only ever happen once per key */ - return 1; - } - key->g = bn; - break; - case 3: - /* Public */ - if (key->y) { - /* This should only ever happen once per key */ - return 1; - } - key->y = bn; - break; - } - - return 0; -} - -static void pgpFreeKeyDSA(pgpDigAlg pgpkey) -{ - struct pgpDigKeyDSA_s *key = pgpkey->data; - if (key) { - if (key->evp_pkey) { - EVP_PKEY_free(key->evp_pkey); - } else { - /* If sig->dsa_key was constructed, - * the memory management of these BNs - * are freed with it. */ - BN_clear_free(key->p); - BN_clear_free(key->q); - BN_clear_free(key->g); - BN_clear_free(key->y); - } - free(key); - } -} - -/* Signature */ - -struct pgpDigSigDSA_s { - BIGNUM *r; - BIGNUM *s; - - DSA_SIG *dsa_sig; -}; - -static int constructDSASignature(struct pgpDigSigDSA_s *sig) -{ - int rc; - - if (sig->dsa_sig) { - /* We've already constructed it, so just reuse it */ - return 1; - } - - /* Create the DSA signature */ - DSA_SIG *dsa_sig = DSA_SIG_new(); - if (!dsa_sig) return 0; - - if (!DSA_SIG_set0(dsa_sig, sig->r, sig->s)) { - rc = 0; - goto done; - } - - sig->dsa_sig = dsa_sig; - - rc = 1; -done: - if (rc == 0) { - DSA_SIG_free(sig->dsa_sig); - } - return rc; -} - -static int pgpSetSigMpiDSA(pgpDigAlg pgpsig, int num, const uint8_t *p) -{ - BIGNUM *bn = NULL; - - int mlen = pgpMpiLen(p) - 2; - int rc = 1; - - struct pgpDigSigDSA_s *sig = pgpsig->data; - if (!sig) { - sig = xcalloc(1, sizeof(*sig)); - } - - /* Create a BIGNUM from the signature pointer. - Note: this assumes big-endian data as required - by the PGP multiprecision integer format - (RFC4880, Section 3.2) */ - bn = BN_bin2bn(p+2, mlen, NULL); - if (!bn) return 1; - - switch (num) { - case 0: - if (sig->r) { - /* This should only ever happen once per signature */ - BN_free(bn); - return 1; - } - sig->r = bn; - rc = 0; - break; - case 1: - if (sig->s) { - /* This should only ever happen once per signature */ - BN_free(bn); - return 1; - } - sig->s = bn; - rc = 0; - break; - } - - pgpsig->data = sig; - - return rc; -} - -static void pgpFreeSigDSA(pgpDigAlg pgpsig) -{ - struct pgpDigSigDSA_s *sig = pgpsig->data; - if (sig) { - if (sig->dsa_sig) { - DSA_SIG_free(sig->dsa_sig); - } else { - /* If sig->dsa_sig was constructed, - * the memory management of these BNs - * are freed with it. */ - BN_clear_free(sig->r); - BN_clear_free(sig->s); - } - free(pgpsig->data); - } -} - -static int pgpVerifySigDSA(pgpDigAlg pgpkey, pgpDigAlg pgpsig, - uint8_t *hash, size_t hashlen, int hash_algo) -{ - int rc = 1; /* assume failure */ - EVP_PKEY_CTX *pkey_ctx = NULL; - - struct pgpDigSigDSA_s *sig = pgpsig->data; - struct pgpDigKeyDSA_s *key = pgpkey->data; - - void *padded_sig = NULL; - - if (!constructDSASigningKey(key)) - goto done; - - if (!constructDSASignature(sig)) - goto done; - - pkey_ctx = EVP_PKEY_CTX_new(key->evp_pkey, NULL); - if (!pkey_ctx) - goto done; - - if (EVP_PKEY_verify_init(pkey_ctx) != 1) - goto done; - - if (EVP_PKEY_CTX_set_signature_md(pkey_ctx, getEVPMD(hash_algo)) <= 0) - goto done; - - int pkey_len = EVP_PKEY_size(key->evp_pkey); - padded_sig = xcalloc(1, pkey_len); - if (BN_bn2binpad(sig->r, padded_sig, pkey_len) <= 0) - goto done; - - if (EVP_PKEY_verify(pkey_ctx, padded_sig, pkey_len, hash, hashlen) == 1) - { - /* Success */ - rc = 0; - } - -done: - return rc; -} - - -/****************************** EDDSA ***************************************/ - -#ifdef EVP_PKEY_ED25519 - -struct pgpDigKeyEDDSA_s { - EVP_PKEY *evp_pkey; /* Fully constructed key */ - unsigned char *q; /* compressed point */ - int qlen; -}; - -static int constructEDDSASigningKey(struct pgpDigKeyEDDSA_s *key, int curve) -{ - if (key->evp_pkey) - return 1; /* We've already constructed it, so just reuse it */ - if (curve == PGPCURVE_ED25519) - key->evp_pkey = EVP_PKEY_new_raw_public_key(EVP_PKEY_ED25519, NULL, key->q, key->qlen); - return key->evp_pkey ? 1 : 0; -} - -static int pgpSetKeyMpiEDDSA(pgpDigAlg pgpkey, int num, const uint8_t *p) -{ - size_t mlen = pgpMpiLen(p) - 2; - struct pgpDigKeyEDDSA_s *key = pgpkey->data; - int rc = 1; - - if (!key) - key = pgpkey->data = xcalloc(1, sizeof(*key)); - if (num == 0 && !key->q && mlen > 1 && p[2] == 0x40) { - key->qlen = mlen - 1; - key->q = xmalloc(key->qlen); - memcpy(key->q, p + 3, key->qlen), - rc = 0; - } - return rc; -} - -static void pgpFreeKeyEDDSA(pgpDigAlg pgpkey) -{ - struct pgpDigKeyEDDSA_s *key = pgpkey->data; - if (key) { - if (key->q) - free(key->q); - if (key->evp_pkey) - EVP_PKEY_free(key->evp_pkey); - free(key); - } -} - -struct pgpDigSigEDDSA_s { - unsigned char sig[32 + 32]; -}; - -static int pgpSetSigMpiEDDSA(pgpDigAlg pgpsig, int num, const uint8_t *p) -{ - struct pgpDigSigEDDSA_s *sig = pgpsig->data; - int mlen = pgpMpiLen(p) - 2; - - if (!sig) - sig = pgpsig->data = xcalloc(1, sizeof(*sig)); - if (!mlen || mlen > 32 || (num != 0 && num != 1)) - return 1; - memcpy(sig->sig + 32 * num + 32 - mlen, p + 2, mlen); - return 0; -} - -static void pgpFreeSigEDDSA(pgpDigAlg pgpsig) -{ - struct pgpDigSigEDDSA_s *sig = pgpsig->data; - if (sig) { - free(pgpsig->data); - } -} - -static int pgpVerifySigEDDSA(pgpDigAlg pgpkey, pgpDigAlg pgpsig, - uint8_t *hash, size_t hashlen, int hash_algo) -{ - int rc = 1; /* assume failure */ - struct pgpDigSigEDDSA_s *sig = pgpsig->data; - struct pgpDigKeyEDDSA_s *key = pgpkey->data; - EVP_MD_CTX *md_ctx = NULL; - - if (!constructEDDSASigningKey(key, pgpkey->curve)) - goto done; - md_ctx = EVP_MD_CTX_new(); - if (EVP_DigestVerifyInit(md_ctx, NULL, EVP_md_null(), NULL, key->evp_pkey) != 1) - goto done; - if (EVP_DigestVerify(md_ctx, sig->sig, 64, hash, hashlen) == 1) - rc = 0; /* Success */ -done: - if (md_ctx) - EVP_MD_CTX_free(md_ctx); - return rc; -} - -#endif - - -/****************************** NULL **************************************/ - -static int pgpSetMpiNULL(pgpDigAlg pgpkey, int num, const uint8_t *p) -{ - return 1; -} - -static int pgpVerifyNULL(pgpDigAlg pgpkey, pgpDigAlg pgpsig, - uint8_t *hash, size_t hashlen, int hash_algo) -{ - return 1; -} - -/****************************** PGP **************************************/ -pgpDigAlg pgpPubkeyNew(int algo, int curve) -{ - pgpDigAlg ka = xcalloc(1, sizeof(*ka));; - - switch (algo) { - case PGPPUBKEYALGO_RSA: - ka->setmpi = pgpSetKeyMpiRSA; - ka->free = pgpFreeKeyRSA; - ka->mpis = 2; - break; - case PGPPUBKEYALGO_DSA: - ka->setmpi = pgpSetKeyMpiDSA; - ka->free = pgpFreeKeyDSA; - ka->mpis = 4; - break; -#ifdef EVP_PKEY_ED25519 - case PGPPUBKEYALGO_EDDSA: - if (curve != PGPCURVE_ED25519) { - ka->setmpi = pgpSetMpiNULL; /* unsupported curve */ - ka->mpis = -1; - break; - } - ka->setmpi = pgpSetKeyMpiEDDSA; - ka->free = pgpFreeKeyEDDSA; - ka->mpis = 1; - ka->curve = curve; - break; -#endif - default: - ka->setmpi = pgpSetMpiNULL; - ka->mpis = -1; - break; - } - - ka->verify = pgpVerifyNULL; /* keys can't be verified */ - - return ka; -} - -pgpDigAlg pgpSignatureNew(int algo) -{ - pgpDigAlg sa = xcalloc(1, sizeof(*sa)); - - switch (algo) { - case PGPPUBKEYALGO_RSA: - sa->setmpi = pgpSetSigMpiRSA; - sa->free = pgpFreeSigRSA; - sa->verify = pgpVerifySigRSA; - sa->mpis = 1; - break; - case PGPPUBKEYALGO_DSA: - sa->setmpi = pgpSetSigMpiDSA; - sa->free = pgpFreeSigDSA; - sa->verify = pgpVerifySigDSA; - sa->mpis = 2; - break; -#ifdef EVP_PKEY_ED25519 - case PGPPUBKEYALGO_EDDSA: - sa->setmpi = pgpSetSigMpiEDDSA; - sa->free = pgpFreeSigEDDSA; - sa->verify = pgpVerifySigEDDSA; - sa->mpis = 2; - break; -#endif - default: - sa->setmpi = pgpSetMpiNULL; - sa->verify = pgpVerifyNULL; - sa->mpis = -1; - break; - } - return sa; -} diff --git a/rpmio/rpmpgp_legacy/rpmpgp_internal.c b/rpmio/rpmpgp_legacy/rpmpgp_internal.c deleted file mode 100644 index 3662e5eeb7..0000000000 --- a/rpmio/rpmpgp_legacy/rpmpgp_internal.c +++ /dev/null @@ -1,1423 +0,0 @@ -/** \ingroup rpmio signature - * \file rpmio/rpmpgp_internal.c - * Routines to handle RFC-2440 detached signatures. - */ - -#include "system.h" - -#include -#include -#include -#include -#include - -#include "rpmpgpval.h" -#include "rpmpgp_internal.h" - -#include "debug.h" - -static int _print = 0; - -typedef uint8_t pgpTime_t[4]; - -typedef struct pgpPktKeyV3_s { - uint8_t version; /*!< version number (3). */ - pgpTime_t time; /*!< time that the key was created. */ - uint8_t valid[2]; /*!< time in days that this key is valid. */ - uint8_t pubkey_algo; /*!< public key algorithm. */ -} * pgpPktKeyV3; - -typedef struct pgpPktKeyV4_s { - uint8_t version; /*!< version number (4). */ - pgpTime_t time; /*!< time that the key was created. */ - uint8_t pubkey_algo; /*!< public key algorithm. */ -} * pgpPktKeyV4; - -typedef struct pgpPktSigV3_s { - uint8_t version; /*!< version number (3). */ - uint8_t hashlen; /*!< length of following hashed material. MUST be 5. */ - uint8_t sigtype; /*!< signature type. */ - pgpTime_t time; /*!< 4 byte creation time. */ - pgpKeyID_t signid; /*!< key ID of signer. */ - uint8_t pubkey_algo; /*!< public key algorithm. */ - uint8_t hash_algo; /*!< hash algorithm. */ - uint8_t signhash16[2]; /*!< left 16 bits of signed hash value. */ -} * pgpPktSigV3; - -typedef struct pgpPktSigV4_s { - uint8_t version; /*!< version number (4). */ - uint8_t sigtype; /*!< signature type. */ - uint8_t pubkey_algo; /*!< public key algorithm. */ - uint8_t hash_algo; /*!< hash algorithm. */ - uint8_t hashlen[2]; /*!< length of following hashed material. */ -} * pgpPktSigV4; - -/** \ingroup rpmio - * Values parsed from OpenPGP signature/pubkey packet(s). - */ -struct pgpDigParams_s { - char * userid; - uint8_t * hash; - uint8_t tag; - - uint8_t key_flags; /*!< key usage flags */ - uint8_t version; /*!< version number. */ - uint32_t time; /*!< key/signature creation time. */ - uint8_t pubkey_algo; /*!< public key algorithm. */ - - uint8_t hash_algo; - uint8_t sigtype; - uint32_t hashlen; - uint8_t signhash16[2]; - pgpKeyID_t signid; - uint8_t saved; /*!< Various flags. `PGPDIG_SAVED_*` are never reset. - * `PGPDIG_SIG_HAS_*` are reset for each signature. */ -#define PGPDIG_SAVED_TIME (1 << 0) -#define PGPDIG_SAVED_ID (1 << 1) -#define PGPDIG_SIG_HAS_CREATION_TIME (1 << 2) -#define PGPDIG_SIG_HAS_KEY_FLAGS (1 << 3) - - pgpDigAlg alg; -}; - -static void pgpPrtNL(void) -{ - if (!_print) return; - fprintf(stderr, "\n"); -} - -static void pgpPrtHex(const char *pre, const uint8_t *p, size_t plen) -{ - char *hex = NULL; - if (!_print) return; - if (pre && *pre) - fprintf(stderr, "%s", pre); - hex = rpmhex(p, plen); - fprintf(stderr, " %s", hex); - free(hex); -} - -static void pgpPrtVal(const char * pre, pgpValType vt, uint8_t val) -{ - if (!_print) return; - if (pre && *pre) - fprintf(stderr, "%s", pre); - fprintf(stderr, "%s(%u)", pgpValString(vt, val), (unsigned)val); -} - -static void pgpPrtTime(const char * pre, const uint8_t *p, size_t plen) -{ - if (!_print) return; - if (pre && *pre) - fprintf(stderr, "%s", pre); - if (plen == 4) { - char buf[1024]; - time_t t = pgpGrab(p, plen); - struct tm _tm, *tms = localtime_r(&t, &_tm); - if (strftime(buf, sizeof(buf), "%c", tms) > 0) - fprintf(stderr, " %-24.24s(0x%08x)", buf, (unsigned)t); - } else { - pgpPrtHex("", p+1, plen-1); - } -} - -/** \ingroup rpmpgp - * Return value of an OpenPGP string. - * @param vs table of (string,value) pairs - * @param s string token to lookup - * @param se end-of-string address - * @return byte value - */ -static inline -int pgpValTok(pgpValTbl vs, const char * s, const char * se) -{ - do { - size_t vlen = strlen(vs->str); - if (vlen <= (se-s) && rstreqn(s, vs->str, vlen)) - break; - } while ((++vs)->val != -1); - return vs->val; -} - -/** \ingroup rpmpgp - * Decode length from 1, 2, or 5 octet body length encoding, used in - * new format packet headers and V4 signature subpackets. - * Partial body lengths are (intentionally) not supported. - * @param s pointer to length encoding buffer - * @param slen buffer size - * @param[out] *lenp decoded length - * @return no. of bytes used to encode the length, 0 on error - */ -static inline -size_t pgpLen(const uint8_t *s, size_t slen, size_t * lenp) -{ - size_t dlen = 0; - size_t lenlen = 0; - - /* - * Callers can only ensure we'll always have the first byte, beyond - * that the required size is not known until we decode it so we need - * to check if we have enough bytes to read the size as we go. - */ - if (*s < 192) { - lenlen = 1; - dlen = *s; - } else if (*s < 224 && slen > 2) { - lenlen = 2; - dlen = (((s[0]) - 192) << 8) + s[1] + 192; - } else if (*s == 255 && slen > 5) { - lenlen = 5; - dlen = pgpGrab(s+1, 4); - } - - if (slen - lenlen < dlen) - lenlen = 0; - - if (lenlen) - *lenp = dlen; - - return lenlen; -} - -struct pgpPkt { - uint8_t tag; /* decoded PGP tag */ - const uint8_t *head; /* pointer to start of packet (header) */ - const uint8_t *body; /* pointer to packet body */ - size_t blen; /* length of body in bytes */ -}; - -/** \ingroup rpmpgp - * Read a length field `nbytes` long. Checks that the buffer is big enough to - * hold `nbytes + *valp` bytes. - * @param s pointer to read from - * @param nbytes length of length field - * @param send pointer past end of buffer - * @param[out] *valp decoded length - * @return 0 if buffer can hold `nbytes + *valp` of data, - * otherwise -1. - */ -static int pgpGet(const uint8_t *s, size_t nbytes, const uint8_t *send, - size_t *valp) -{ - int rc = -1; - - *valp = 0; - if (nbytes <= 4 && send - s >= nbytes) { - unsigned int val = pgpGrab(s, nbytes); - if (send - s - nbytes >= val) { - rc = 0; - *valp = val; - } - } - - return rc; -} - -static int decodePkt(const uint8_t *p, size_t plen, struct pgpPkt *pkt) -{ - int rc = -1; /* assume failure */ - - /* Valid PGP packet header must always have two or more bytes in it */ - if (p && plen >= 2 && p[0] & 0x80) { - size_t lenlen = 0; - size_t hlen = 0; - - if (p[0] & 0x40) { - /* New format packet, body length encoding in second byte */ - lenlen = pgpLen(p+1, plen-1, &pkt->blen); - pkt->tag = (p[0] & 0x3f); - } else { - /* Old format packet, body length encoding in tag byte */ - lenlen = (1 << (p[0] & 0x3)); - /* Reject indefinite length packets and check bounds */ - if (pgpGet(p + 1, lenlen, p + plen, &pkt->blen)) - return rc; - pkt->tag = (p[0] >> 2) & 0xf; - } - hlen = lenlen + 1; - - /* Does the packet header and its body fit in our boundaries? */ - if (lenlen && (hlen + pkt->blen <= plen)) { - pkt->head = p; - pkt->body = pkt->head + hlen; - rc = 0; - } - } - - return rc; -} - -#define CRC24_INIT 0xb704ce -#define CRC24_POLY 0x1864cfb - -/** \ingroup rpmpgp - * Return CRC of a buffer. - * @param octets bytes - * @param len no. of bytes - * @return crc of buffer - */ -static inline -unsigned int pgpCRC(const uint8_t *octets, size_t len) -{ - unsigned int crc = CRC24_INIT; - size_t i; - - while (len--) { - crc ^= (*octets++) << 16; - for (i = 0; i < 8; i++) { - crc <<= 1; - if (crc & 0x1000000) - crc ^= CRC24_POLY; - } - } - return crc & 0xffffff; -} - -static int pgpVersion(const uint8_t *h, size_t hlen, uint8_t *version) -{ - if (hlen < 1) - return -1; - - *version = h[0]; - return 0; -} - -int pgpSignatureType(pgpDigParams _digp) -{ - int rc = -1; - - if (_digp && _digp->tag == PGPTAG_SIGNATURE) - rc = _digp->sigtype; - - return rc; -} - -static int pgpPrtSubType(const uint8_t *h, size_t hlen, pgpSigType sigtype, - pgpDigParams _digp, int hashed) -{ - const uint8_t *p = h; - size_t plen = 0, i; - int rc = 0; - - while (hlen > 0 && rc == 0) { - int impl = 0; - i = pgpLen(p, hlen, &plen); - if (i == 0 || plen < 1 || i + plen > hlen) - break; - - p += i; - hlen -= i; - - pgpPrtVal(" ", PGPVAL_SUBTYPE, (p[0]&(~PGPSUBTYPE_CRITICAL))); - if (p[0] & PGPSUBTYPE_CRITICAL) - if (_print) - fprintf(stderr, " *CRITICAL*"); - switch (*p & ~PGPSUBTYPE_CRITICAL) { - case PGPSUBTYPE_PREFER_SYMKEY: /* preferred symmetric algorithms */ - for (i = 1; i < plen; i++) - pgpPrtVal(" ", PGPVAL_SYMKEYALGO, p[i]); - break; - case PGPSUBTYPE_PREFER_HASH: /* preferred hash algorithms */ - for (i = 1; i < plen; i++) - pgpPrtVal(" ", PGPVAL_HASHALGO, p[i]); - break; - case PGPSUBTYPE_PREFER_COMPRESS:/* preferred compression algorithms */ - for (i = 1; i < plen; i++) - pgpPrtVal(" ", PGPVAL_COMPRESSALGO, p[i]); - break; - case PGPSUBTYPE_KEYSERVER_PREFERS:/* key server preferences */ - for (i = 1; i < plen; i++) - pgpPrtVal(" ", PGPVAL_SERVERPREFS, p[i]); - break; - case PGPSUBTYPE_SIG_CREATE_TIME: /* signature creation time */ - if (!hashed) - break; /* RFC 4880 §5.2.3.4 creation time MUST be hashed */ - if (plen-1 != sizeof(_digp->time)) - break; /* other lengths not understood */ - if (_digp->saved & PGPDIG_SIG_HAS_CREATION_TIME) - return 1; /* duplicate timestamps not allowed */ - impl = *p; - if (!(_digp->saved & PGPDIG_SAVED_TIME)) - _digp->time = pgpGrab(p+1, sizeof(_digp->time)); - _digp->saved |= PGPDIG_SAVED_TIME | PGPDIG_SIG_HAS_CREATION_TIME; - break; - case PGPSUBTYPE_SIG_EXPIRE_TIME: - case PGPSUBTYPE_KEY_EXPIRE_TIME: - pgpPrtTime(" ", p+1, plen-1); - break; - - case PGPSUBTYPE_ISSUER_KEYID: /* issuer key ID */ - impl = *p; - if (!(_digp->saved & PGPDIG_SAVED_ID) && - (sigtype == PGPSIGTYPE_POSITIVE_CERT || sigtype == PGPSIGTYPE_BINARY || sigtype == PGPSIGTYPE_TEXT || sigtype == PGPSIGTYPE_STANDALONE)) - { - if (plen-1 != sizeof(_digp->signid)) - break; - _digp->saved |= PGPDIG_SAVED_ID; - memcpy(_digp->signid, p+1, sizeof(_digp->signid)); - } - break; - case PGPSUBTYPE_KEY_FLAGS: /* Key usage flags */ - /* Subpackets in the unhashed section cannot be trusted */ - if (!hashed) - break; - /* Reject duplicate key usage flags */ - if (_digp->saved & PGPDIG_SIG_HAS_KEY_FLAGS) - return 1; - impl = *p; - _digp->saved |= PGPDIG_SIG_HAS_KEY_FLAGS; - _digp->key_flags = plen >= 2 ? p[1] : 0; - break; - case PGPSUBTYPE_EXPORTABLE_CERT: - case PGPSUBTYPE_TRUST_SIG: - case PGPSUBTYPE_REGEX: - case PGPSUBTYPE_REVOCABLE: - case PGPSUBTYPE_ARR: - case PGPSUBTYPE_REVOKE_KEY: - case PGPSUBTYPE_NOTATION: - case PGPSUBTYPE_PREFER_KEYSERVER: - case PGPSUBTYPE_PRIMARY_USERID: - case PGPSUBTYPE_POLICY_URL: - case PGPSUBTYPE_SIGNER_USERID: - case PGPSUBTYPE_REVOKE_REASON: - case PGPSUBTYPE_FEATURES: - case PGPSUBTYPE_EMBEDDED_SIG: - case PGPSUBTYPE_INTERNAL_100: - case PGPSUBTYPE_INTERNAL_101: - case PGPSUBTYPE_INTERNAL_102: - case PGPSUBTYPE_INTERNAL_103: - case PGPSUBTYPE_INTERNAL_104: - case PGPSUBTYPE_INTERNAL_105: - case PGPSUBTYPE_INTERNAL_106: - case PGPSUBTYPE_INTERNAL_107: - case PGPSUBTYPE_INTERNAL_108: - case PGPSUBTYPE_INTERNAL_109: - case PGPSUBTYPE_INTERNAL_110: - default: - pgpPrtHex("", p+1, plen-1); - break; - } - pgpPrtNL(); - - if (!impl && (p[0] & PGPSUBTYPE_CRITICAL)) - rc = 1; - - p += plen; - hlen -= plen; - } - - if (hlen != 0) - rc = 1; - - return rc; -} - -pgpDigAlg pgpDigAlgFree(pgpDigAlg alg) -{ - if (alg) { - if (alg->free) - alg->free(alg); - free(alg); - } - return NULL; -} - -static int processMpis(const int mpis, pgpDigAlg sigalg, - const uint8_t *p, const uint8_t *const pend) -{ - int i = 0, rc = 1; /* assume failure */ - for (; i < mpis && pend - p >= 2; i++) { - unsigned int mpil = pgpMpiLen(p); - if (pend - p < mpil) - return rc; - if (sigalg && sigalg->setmpi(sigalg, i, p)) - return rc; - p += mpil; - } - - /* Does the size and number of MPI's match our expectations? */ - if (p == pend && i == mpis) - rc = 0; - return rc; -} - -static int pgpPrtSigParams(pgpTag tag, uint8_t pubkey_algo, - const uint8_t *p, const uint8_t *h, size_t hlen, - pgpDigParams sigp) -{ - const uint8_t * pend = h + hlen; - pgpDigAlg sigalg = pgpSignatureNew(pubkey_algo); - - int rc = processMpis(sigalg->mpis, sigalg, p, pend); - - /* We can't handle more than one sig at a time */ - if (rc == 0 && sigp->alg == NULL && sigp->tag == PGPTAG_SIGNATURE) - sigp->alg = sigalg; - else - pgpDigAlgFree(sigalg); - - return rc; -} - -static int pgpPrtSig(pgpTag tag, const uint8_t *h, size_t hlen, - pgpDigParams _digp) -{ - uint8_t version = 0; - const uint8_t * p; - size_t plen; - int rc = 1; - - /* Reset the saved flags */ - _digp->saved &= PGPDIG_SAVED_TIME | PGPDIG_SAVED_ID; - _digp->key_flags = 0; - - if (pgpVersion(h, hlen, &version)) - return rc; - - switch (version) { - case 3: - { pgpPktSigV3 v = (pgpPktSigV3)h; - - if (hlen <= sizeof(*v) || v->hashlen != 5) - return 1; - - pgpPrtVal("V3 ", PGPVAL_TAG, tag); - pgpPrtVal(" ", PGPVAL_PUBKEYALGO, v->pubkey_algo); - pgpPrtVal(" ", PGPVAL_HASHALGO, v->hash_algo); - pgpPrtVal(" ", PGPVAL_SIGTYPE, v->sigtype); - pgpPrtNL(); - pgpPrtTime(" ", v->time, sizeof(v->time)); - pgpPrtNL(); - pgpPrtHex(" signer keyid", v->signid, sizeof(v->signid)); - plen = pgpGrab(v->signhash16, sizeof(v->signhash16)); - pgpPrtHex(" signhash16", v->signhash16, sizeof(v->signhash16)); - pgpPrtNL(); - - if (_digp->pubkey_algo == 0) { - _digp->version = v->version; - _digp->hashlen = v->hashlen; - _digp->sigtype = v->sigtype; - _digp->hash = memcpy(xmalloc(v->hashlen), &v->sigtype, v->hashlen); - if (!(_digp->saved & PGPDIG_SAVED_TIME)) - _digp->time = pgpGrab(v->time, sizeof(v->time)); - if (!(_digp->saved & PGPDIG_SAVED_ID)) - memcpy(_digp->signid, v->signid, sizeof(_digp->signid)); - _digp->saved = PGPDIG_SAVED_TIME | PGPDIG_SIG_HAS_CREATION_TIME | PGPDIG_SAVED_ID; - _digp->pubkey_algo = v->pubkey_algo; - _digp->hash_algo = v->hash_algo; - memcpy(_digp->signhash16, v->signhash16, sizeof(_digp->signhash16)); - } - - p = ((uint8_t *)v) + sizeof(*v); - rc = tag ? pgpPrtSigParams(tag, v->pubkey_algo, p, h, hlen, _digp) : 0; - } break; - case 4: - { pgpPktSigV4 v = (pgpPktSigV4)h; - const uint8_t *const hend = h + hlen; - - if (hlen <= sizeof(*v)) - return 1; - - pgpPrtVal("V4 ", PGPVAL_TAG, tag); - pgpPrtVal(" ", PGPVAL_PUBKEYALGO, v->pubkey_algo); - pgpPrtVal(" ", PGPVAL_HASHALGO, v->hash_algo); - pgpPrtVal(" ", PGPVAL_SIGTYPE, v->sigtype); - pgpPrtNL(); - - p = &v->hashlen[0]; - if (pgpGet(v->hashlen, sizeof(v->hashlen), hend, &plen)) - return 1; - p += sizeof(v->hashlen); - - if ((p + plen) > hend) - return 1; - - if (_digp->pubkey_algo == 0) { - _digp->hashlen = sizeof(*v) + plen; - _digp->hash = memcpy(xmalloc(_digp->hashlen), v, _digp->hashlen); - } - if (pgpPrtSubType(p, plen, v->sigtype, _digp, 1)) - return 1; - p += plen; - - if (!(_digp->saved & PGPDIG_SIG_HAS_CREATION_TIME)) - return 1; /* RFC 4880 §5.2.3.4 creation time MUST be hashed */ - - if (pgpGet(p, 2, hend, &plen)) - return 1; - p += 2; - - if ((p + plen) > hend) - return 1; - - if (pgpPrtSubType(p, plen, v->sigtype, _digp, 0)) - return 1; - p += plen; - - if (h + hlen - p < 2) - return 1; - pgpPrtHex(" signhash16", p, 2); - pgpPrtNL(); - - if (_digp->pubkey_algo == 0) { - _digp->version = v->version; - _digp->sigtype = v->sigtype; - _digp->pubkey_algo = v->pubkey_algo; - _digp->hash_algo = v->hash_algo; - memcpy(_digp->signhash16, p, sizeof(_digp->signhash16)); - } - - p += 2; - if (p > hend) - return 1; - - rc = tag ? pgpPrtSigParams(tag, v->pubkey_algo, p, h, hlen, _digp) : 0; - } break; - default: - rpmlog(RPMLOG_WARNING, _("Unsupported version of signature: V%d\n"), version); - rc = 1; - break; - } - return rc; -} - -static uint8_t curve_oids[] = { - PGPCURVE_NIST_P_256, 0x08, 0x2a, 0x86, 0x48, 0xce, 0x3d, 0x03, 0x01, 0x07, - PGPCURVE_NIST_P_384, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x22, - PGPCURVE_NIST_P_521, 0x05, 0x2b, 0x81, 0x04, 0x00, 0x23, - PGPCURVE_BRAINPOOL_P256R1, 0x09, 0x2b, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x07, - PGPCURVE_BRAINPOOL_P512R1, 0x09, 0x2b, 0x24, 0x03, 0x03, 0x02, 0x08, 0x01, 0x01, 0x0d, - PGPCURVE_ED25519, 0x09, 0x2b, 0x06, 0x01, 0x04, 0x01, 0xda, 0x47, 0x0f, 0x01, - PGPCURVE_CURVE25519, 0x0a, 0x2b, 0x06, 0x01, 0x04, 0x01, 0x97, 0x55, 0x01, 0x05, 0x01, - 0, -}; - -static int pgpCurveByOid(const uint8_t *p, int l) -{ - uint8_t *curve; - for (curve = curve_oids; *curve; curve += 2 + curve[1]) - if (l == (int)curve[1] && !memcmp(p, curve + 2, l)) - return (int)curve[0]; - return 0; -} - -static int isKey(pgpDigParams keyp) -{ - return keyp->tag == PGPTAG_PUBLIC_KEY || keyp->tag == PGPTAG_PUBLIC_SUBKEY; -} - -static int pgpPrtPubkeyParams(uint8_t pubkey_algo, - const uint8_t *p, const uint8_t *h, size_t hlen, - pgpDigParams keyp) -{ - int rc = 1; /* assume failure */ - const uint8_t *pend = h + hlen; - int curve = 0; - if (!isKey(keyp)) - return rc; - /* We can't handle more than one key at a time */ - if (keyp->alg) - return rc; - if (pubkey_algo == PGPPUBKEYALGO_EDDSA) { - int len = (hlen > 1) ? p[0] : 0; - if (len == 0 || len == 0xff || len >= hlen) - return rc; - curve = pgpCurveByOid(p + 1, len); - p += len + 1; - } - pgpDigAlg keyalg = pgpPubkeyNew(pubkey_algo, curve); - rc = processMpis(keyalg->mpis, keyalg, p, pend); - if (rc == 0) { - keyp->pubkey_algo = pubkey_algo; - keyp->alg = keyalg; - } else { - pgpDigAlgFree(keyalg); - } - return rc; -} - -static int pgpPrtKey(pgpTag tag, const uint8_t *h, size_t hlen, - pgpDigParams _digp) -{ - uint8_t version = 0; - const uint8_t * p = NULL; - int rc = 1; - - if (pgpVersion(h, hlen, &version)) - return rc; - - /* We only permit V4 keys, V3 keys are long long since deprecated */ - switch (version) { - case 4: - { pgpPktKeyV4 v = (pgpPktKeyV4)h; - - if (hlen > sizeof(*v)) { - pgpPrtVal("V4 ", PGPVAL_TAG, tag); - pgpPrtVal(" ", PGPVAL_PUBKEYALGO, v->pubkey_algo); - pgpPrtTime(" ", v->time, sizeof(v->time)); - pgpPrtNL(); - - /* If _digp->hash is not NULL then signature is already loaded */ - if (_digp->hash == NULL) { - _digp->version = v->version; - if (!(_digp->saved & PGPDIG_SAVED_TIME)) - _digp->time = pgpGrab(v->time, sizeof(v->time)); - _digp->saved |= PGPDIG_SAVED_TIME | PGPDIG_SIG_HAS_CREATION_TIME; - } - - p = ((uint8_t *)v) + sizeof(*v); - rc = pgpPrtPubkeyParams(v->pubkey_algo, p, h, hlen, _digp); - } - } break; - default: - rpmlog(RPMLOG_WARNING, _("Unsupported version of key: V%d\n"), h[0]); - } - return rc; -} - -static int pgpPrtUserID(pgpTag tag, const uint8_t *h, size_t hlen, - pgpDigParams _digp) -{ - pgpPrtVal("", PGPVAL_TAG, tag); - if (_print) - fprintf(stderr, " \"%.*s\"", (int)hlen, (const char *)h); - pgpPrtNL(); - free(_digp->userid); - _digp->userid = memcpy(xmalloc(hlen+1), h, hlen); - _digp->userid[hlen] = '\0'; - return 0; -} - -static int getPubkeyFingerprint(const uint8_t *h, size_t hlen, - uint8_t **fp, size_t *fplen) -{ - int rc = -1; /* assume failure */ - const uint8_t *se; - const uint8_t *pend = h + hlen; - uint8_t version = 0; - - if (pgpVersion(h, hlen, &version)) - return rc; - - /* We only permit V4 keys, V3 keys are long long since deprecated */ - switch (version) { - case 4: - { pgpPktKeyV4 v = (pgpPktKeyV4) (h); - int mpis = -1; - - /* Packet must be strictly larger than v to have room for the - * required MPIs and (for EdDSA) the curve ID */ - if (hlen < sizeof(*v) + sizeof(uint8_t)) - return rc; - se = (uint8_t *)(v + 1); - switch (v->pubkey_algo) { - case PGPPUBKEYALGO_EDDSA: - /* EdDSA has a curve id before the MPIs */ - if (se[0] == 0x00 || se[0] == 0xff || pend - se < 1 + se[0]) - return rc; - se += 1 + se[0]; - mpis = 1; - break; - case PGPPUBKEYALGO_RSA: - mpis = 2; - break; - case PGPPUBKEYALGO_DSA: - mpis = 4; - break; - default: - return rc; - } - - /* Does the size and number of MPI's match our expectations? */ - if (processMpis(mpis, NULL, se, pend) == 0) { - DIGEST_CTX ctx = rpmDigestInit(RPM_HASH_SHA1, RPMDIGEST_NONE); - uint8_t *d = NULL; - size_t dlen = 0; - uint8_t in[3] = { 0x99, (hlen >> 8), hlen }; - - (void) rpmDigestUpdate(ctx, in, 3); - (void) rpmDigestUpdate(ctx, h, hlen); - (void) rpmDigestFinal(ctx, (void **)&d, &dlen, 0); - - if (dlen == 20) { - rc = 0; - *fp = d; - *fplen = dlen; - } else { - free(d); - } - } - - } break; - default: - rpmlog(RPMLOG_WARNING, _("Unsupported version of key: V%d\n"), version); - } - return rc; -} - -int pgpPubkeyFingerprint(const uint8_t * pkt, size_t pktlen, - uint8_t **fp, size_t *fplen) -{ - struct pgpPkt p; - - if (decodePkt(pkt, pktlen, &p)) - return -1; - - return getPubkeyFingerprint(p.body, p.blen, fp, fplen); -} - -static int getKeyID(const uint8_t *h, size_t hlen, pgpKeyID_t keyid) -{ - uint8_t *fp = NULL; - size_t fplen = 0; - int rc = getPubkeyFingerprint(h, hlen, &fp, &fplen); - if (fp && fplen > 8) { - memcpy(keyid, (fp + (fplen-8)), 8); - free(fp); - } - return rc; -} - -int pgpPubkeyKeyID(const uint8_t * pkt, size_t pktlen, pgpKeyID_t keyid) -{ - struct pgpPkt p; - - if (decodePkt(pkt, pktlen, &p)) - return -1; - - return getKeyID(p.body, p.blen, keyid); -} - -static int pgpPrtPkt(struct pgpPkt *p, pgpDigParams _digp) -{ - int rc = 0; - - switch (p->tag) { - case PGPTAG_SIGNATURE: - rc = pgpPrtSig(p->tag, p->body, p->blen, _digp); - break; - case PGPTAG_PUBLIC_KEY: - /* Get the public key Key ID. */ - rc = getKeyID(p->body, p->blen, _digp->signid); - if (rc) - memset(_digp->signid, 0, sizeof(_digp->signid)); - else { - _digp->saved |= PGPDIG_SAVED_ID; - rc = pgpPrtKey(p->tag, p->body, p->blen, _digp); - } - break; - case PGPTAG_USER_ID: - rc = pgpPrtUserID(p->tag, p->body, p->blen, _digp); - break; - case PGPTAG_RESERVED: - rc = -1; - break; - case PGPTAG_COMMENT: - case PGPTAG_COMMENT_OLD: - case PGPTAG_PUBLIC_SUBKEY: - case PGPTAG_SECRET_KEY: - case PGPTAG_SECRET_SUBKEY: - case PGPTAG_PUBLIC_SESSION_KEY: - case PGPTAG_SYMMETRIC_SESSION_KEY: - case PGPTAG_COMPRESSED_DATA: - case PGPTAG_SYMMETRIC_DATA: - case PGPTAG_MARKER: - case PGPTAG_LITERAL_DATA: - case PGPTAG_TRUST: - case PGPTAG_PHOTOID: - case PGPTAG_ENCRYPTED_MDC: - case PGPTAG_MDC: - case PGPTAG_PRIVATE_60: - case PGPTAG_PRIVATE_62: - case PGPTAG_CONTROL: - default: - pgpPrtVal("", PGPVAL_TAG, p->tag); - pgpPrtHex("", p->body, p->blen); - pgpPrtNL(); - break; - } - - return rc; -} - -pgpDigParams pgpDigParamsFree(pgpDigParams digp) -{ - if (digp) { - pgpDigAlgFree(digp->alg); - free(digp->userid); - free(digp->hash); - memset(digp, 0, sizeof(*digp)); - free(digp); - } - return NULL; -} - -int pgpDigParamsCmp(pgpDigParams p1, pgpDigParams p2) -{ - int rc = 1; /* assume different, eg if either is NULL */ - if (p1 && p2) { - /* XXX Should we compare something else too? */ - if (p1->tag != p2->tag) - goto exit; - if (p1->hash_algo != p2->hash_algo) - goto exit; - if (p1->pubkey_algo != p2->pubkey_algo) - goto exit; - if (p1->version != p2->version) - goto exit; - if (p1->sigtype != p2->sigtype) - goto exit; - if (memcmp(p1->signid, p2->signid, sizeof(p1->signid)) != 0) - goto exit; - if (p1->userid && p2->userid && strcmp(p1->userid, p2->userid) != 0) - goto exit; - - /* Parameters match ... at least for our purposes */ - rc = 0; - } -exit: - return rc; -} - -unsigned int pgpDigParamsAlgo(pgpDigParams digp, unsigned int algotype) -{ - unsigned int algo = 0; /* assume failure */ - if (digp) { - switch (algotype) { - case PGPVAL_PUBKEYALGO: - algo = digp->pubkey_algo; - break; - case PGPVAL_HASHALGO: - algo = digp->hash_algo; - break; - } - } - return algo; -} - -const uint8_t *pgpDigParamsSignID(pgpDigParams digp) -{ - return digp->signid; -} - -const char *pgpDigParamsUserID(pgpDigParams digp) -{ - return digp->userid; -} - -int pgpDigParamsVersion(pgpDigParams digp) -{ - return digp->version; -} - -uint32_t pgpDigParamsCreationTime(pgpDigParams digp) -{ - return digp->time; -} - -static pgpDigParams pgpDigParamsNew(uint8_t tag) -{ - pgpDigParams digp = xcalloc(1, sizeof(*digp)); - digp->tag = tag; - return digp; -} - -static int hashKey(DIGEST_CTX hash, const struct pgpPkt *pkt, int exptag) -{ - int rc = -1; - if (pkt->tag == exptag) { - uint8_t head[] = { - 0x99, - (pkt->blen >> 8), - (pkt->blen ), - }; - - rpmDigestUpdate(hash, head, 3); - rpmDigestUpdate(hash, pkt->body, pkt->blen); - rc = 0; - } - return rc; -} - -static int pgpVerifySelf(pgpDigParams key, pgpDigParams selfsig, - const struct pgpPkt *all, int i) -{ - int rc = -1; - DIGEST_CTX hash = NULL; - - switch (selfsig->sigtype) { - case PGPSIGTYPE_SUBKEY_BINDING: - hash = rpmDigestInit(selfsig->hash_algo, 0); - if (hash) { - rc = hashKey(hash, &all[0], PGPTAG_PUBLIC_KEY); - if (!rc) - rc = hashKey(hash, &all[i-1], PGPTAG_PUBLIC_SUBKEY); - } - break; - default: - /* ignore types we can't handle */ - rc = 0; - break; - } - - if (hash && rc == 0) - rc = pgpVerifySignature(key, selfsig, hash); - - rpmDigestFinal(hash, NULL, NULL, 0); - - return rc; -} - -static int parseSubkeySig(const struct pgpPkt *pkt, uint8_t tag, - pgpDigParams *params_p) { - pgpDigParams params = *params_p = NULL; /* assume failure */ - - if (pkt->tag != PGPTAG_SIGNATURE) - goto fail; - - params = pgpDigParamsNew(tag); - - if (pgpPrtSig(tag, pkt->body, pkt->blen, params)) - goto fail; - - if (params->sigtype != PGPSIGTYPE_SUBKEY_BINDING && - params->sigtype != PGPSIGTYPE_SUBKEY_REVOKE) - { - goto fail; - } - - *params_p = params; - return 0; -fail: - pgpDigParamsFree(params); - return -1; -} - -static const size_t RPM_MAX_OPENPGP_BYTES = 65535; /* max number of bytes in a key */ - -int pgpPrtParams(const uint8_t * pkts, size_t pktlen, unsigned int pkttype, - pgpDigParams * ret) -{ - const uint8_t *p = pkts; - const uint8_t *pend = pkts + pktlen; - pgpDigParams digp = NULL; - pgpDigParams selfsig = NULL; - int i = 0; - int alloced = 16; /* plenty for normal cases */ - int rc = -1; /* assume failure */ - int expect = 0; - int prevtag = 0; - - if (pktlen > RPM_MAX_OPENPGP_BYTES) - return rc; /* reject absurdly large data */ - - struct pgpPkt *all = xmalloc(alloced * sizeof(*all)); - while (p < pend) { - struct pgpPkt *pkt = &all[i]; - if (decodePkt(p, (pend - p), pkt)) - break; - - if (digp == NULL) { - if (pkttype && pkt->tag != pkttype) { - break; - } else { - digp = pgpDigParamsNew(pkt->tag); - } - } else if (pkt->tag == PGPTAG_PUBLIC_KEY) - break; - - if (expect) { - if (pkt->tag != expect) - break; - selfsig = pgpDigParamsNew(pkt->tag); - } - - if (pgpPrtPkt(pkt, selfsig ? selfsig : digp)) - break; - - if (selfsig) { - /* subkeys must be followed by binding signature */ - int xx = 1; /* assume failure */ - - if (!(prevtag == PGPTAG_PUBLIC_SUBKEY && - selfsig->sigtype != PGPSIGTYPE_SUBKEY_BINDING)) - xx = pgpVerifySelf(digp, selfsig, all, i); - - selfsig = pgpDigParamsFree(selfsig); - if (xx) - break; - expect = 0; - } - - if (pkt->tag == PGPTAG_PUBLIC_SUBKEY) - expect = PGPTAG_SIGNATURE; - prevtag = pkt->tag; - - i++; - p += (pkt->body - pkt->head) + pkt->blen; - if (pkttype == PGPTAG_SIGNATURE) - break; - - if (alloced <= i) { - alloced *= 2; - all = xrealloc(all, alloced * sizeof(*all)); - } - } - - rc = (digp && (p == pend) && expect == 0) ? 0 : -1; - - free(all); - selfsig = pgpDigParamsFree(selfsig); - if (ret && rc == 0) { - *ret = digp; - } else { - pgpDigParamsFree(digp); - } - return rc; -} - -int pgpPrtParams2(const uint8_t * pkts, size_t pktlen, unsigned int pkttype, - pgpDigParams * ret, char **lints) -{ - if (lints) - *lints = NULL; - return pgpPrtParams(pkts, pktlen, pkttype, ret); -} - -int pgpPrtParamsSubkeys(const uint8_t *pkts, size_t pktlen, - pgpDigParams mainkey, pgpDigParams **subkeys, - int *subkeysCount) -{ - const uint8_t *p = pkts; - const uint8_t *pend = pkts + pktlen; - pgpDigParams *digps = NULL; - int count = 0; - int alloced = 10; - struct pgpPkt pkt; - int rc, i; - - digps = xmalloc(alloced * sizeof(*digps)); - - while (p < pend) { - if (decodePkt(p, (pend - p), &pkt)) - break; - - p += (pkt.body - pkt.head) + pkt.blen; - - if (pkt.tag == PGPTAG_PUBLIC_SUBKEY) { - if (count == alloced) { - alloced <<= 1; - digps = xrealloc(digps, alloced * sizeof(*digps)); - } - - digps[count] = pgpDigParamsNew(PGPTAG_PUBLIC_SUBKEY); - /* Copy UID from main key to subkey */ - digps[count]->userid = xstrdup(mainkey->userid); - - if (getKeyID(pkt.body, pkt.blen, digps[count]->signid)) { - pgpDigParamsFree(digps[count]); - continue; - } - - if (pgpPrtKey(pkt.tag, pkt.body, pkt.blen, digps[count])) { - pgpDigParamsFree(digps[count]); - continue; - } - - pgpDigParams subkey_sig = NULL; - if (decodePkt(p, pend - p, &pkt) || - parseSubkeySig(&pkt, 0, &subkey_sig)) - { - pgpDigParamsFree(digps[count]); - break; - } - - /* Is the subkey revoked or incapable of signing? */ - int ignore = subkey_sig->sigtype != PGPSIGTYPE_SUBKEY_BINDING || - !((subkey_sig->saved & PGPDIG_SIG_HAS_KEY_FLAGS) && - (subkey_sig->key_flags & 0x02)); - if (ignore) { - pgpDigParamsFree(digps[count]); - } else { - digps[count]->key_flags = subkey_sig->key_flags; - digps[count]->saved |= PGPDIG_SIG_HAS_KEY_FLAGS; - count++; - } - p += (pkt.body - pkt.head) + pkt.blen; - pgpDigParamsFree(subkey_sig); - } - } - rc = (p == pend) ? 0 : -1; - - if (rc == 0) { - *subkeys = xrealloc(digps, count * sizeof(*digps)); - *subkeysCount = count; - } else { - for (i = 0; i < count; i++) - pgpDigParamsFree(digps[i]); - free(digps); - } - - return rc; -} - -rpmRC pgpVerifySignature(pgpDigParams key, pgpDigParams sig, DIGEST_CTX hashctx) -{ - DIGEST_CTX ctx = rpmDigestDup(hashctx); - uint8_t *hash = NULL; - size_t hashlen = 0; - rpmRC res = RPMRC_FAIL; /* assume failure */ - - if (sig == NULL || ctx == NULL) - goto exit; - - if (sig->tag != PGPTAG_SIGNATURE) - goto exit; - - if (sig->hash != NULL) - rpmDigestUpdate(ctx, sig->hash, sig->hashlen); - - if (sig->version == 4) { - /* V4 trailer is six octets long (rfc4880) */ - uint8_t trailer[6]; - uint32_t nb = sig->hashlen; - nb = htonl(nb); - trailer[0] = sig->version; - trailer[1] = 0xff; - memcpy(trailer+2, &nb, 4); - rpmDigestUpdate(ctx, trailer, sizeof(trailer)); - } - - rpmDigestFinal(ctx, (void **)&hash, &hashlen, 0); - ctx = NULL; - - /* Compare leading 16 bits of digest for quick check. */ - if (hash == NULL || memcmp(hash, sig->signhash16, 2) != 0) - goto exit; - - /* - * If we have a key, verify the signature for real. Otherwise we've - * done all we can, return NOKEY to indicate "looks okay but dunno." - */ - if (key && key->alg) { - if (!isKey(key)) - goto exit; - pgpDigAlg sa = sig->alg; - pgpDigAlg ka = key->alg; - if (sa && sa->verify && sig->pubkey_algo == key->pubkey_algo) { - if (sa->verify(ka, sa, hash, hashlen, sig->hash_algo) == 0) { - res = RPMRC_OK; - } - } - } else { - res = RPMRC_NOKEY; - } - -exit: - free(hash); - rpmDigestFinal(ctx, NULL, NULL, 0); - return res; - -} - -rpmRC pgpVerifySignature2(pgpDigParams key, pgpDigParams sig, DIGEST_CTX hashctx, char **lints) -{ - if (lints) - *lints = NULL; - return pgpVerifySignature(key, sig, hashctx); -} - -static pgpArmor decodePkts(uint8_t *b, uint8_t **pkt, size_t *pktlen) -{ - const char * enc = NULL; - const char * crcenc = NULL; - uint8_t * dec; - uint8_t * crcdec; - size_t declen; - size_t crclen; - uint32_t crcpkt, crc; - const char * armortype = NULL; - char * t, * te; - int pstate = 0; - pgpArmor ec = PGPARMOR_ERR_NO_BEGIN_PGP; /* XXX assume failure */ - -#define TOKEQ(_s, _tok) (rstreqn((_s), (_tok), sizeof(_tok)-1)) - - for (t = (char *)b; t && *t; t = te) { - int rc; - if ((te = strchr(t, '\n')) == NULL) - te = t + strlen(t); - else - te++; - - switch (pstate) { - case 0: - armortype = NULL; - if (!TOKEQ(t, "-----BEGIN PGP ")) - continue; - t += sizeof("-----BEGIN PGP ")-1; - - rc = pgpValTok(pgpArmorTbl, t, te); - if (rc < 0) { - ec = PGPARMOR_ERR_UNKNOWN_ARMOR_TYPE; - goto exit; - } - if (rc != PGPARMOR_PUBKEY) /* XXX ASCII Pubkeys only, please. */ - continue; - - armortype = pgpValString(PGPVAL_ARMORBLOCK, rc); - t += strlen(armortype); - if (!TOKEQ(t, "-----")) - continue; - t += sizeof("-----")-1; - if (*t != '\n' && *t != '\r') - continue; - *t = '\0'; - pstate++; - break; - case 1: - enc = NULL; - rc = pgpValTok(pgpArmorKeyTbl, t, te); - if (rc >= 0) - continue; - if (*t != '\n' && *t != '\r') { - pstate = 0; - continue; - } - enc = te; /* Start of encoded packets */ - pstate++; - break; - case 2: - crcenc = NULL; - if (*t != '=') - continue; - *t++ = '\0'; /* Terminate encoded packets */ - crcenc = t; /* Start of encoded crc */ - pstate++; - break; - case 3: - pstate = 0; - if (!TOKEQ(t, "-----END PGP ")) { - ec = PGPARMOR_ERR_NO_END_PGP; - goto exit; - } - *t = '\0'; /* Terminate encoded crc */ - t += sizeof("-----END PGP ")-1; - if (t >= te) continue; - - if (armortype == NULL) /* XXX can't happen */ - continue; - if (!rstreqn(t, armortype, strlen(armortype))) - continue; - - t += strlen(armortype); - if (t >= te) continue; - - if (!TOKEQ(t, "-----")) { - ec = PGPARMOR_ERR_NO_END_PGP; - goto exit; - } - t += (sizeof("-----")-1); - /* Handle EOF without EOL here, *t == '\0' at EOF */ - if (*t && (t >= te)) continue; - /* XXX permitting \r here is not RFC-2440 compliant */ - if (!(*t == '\n' || *t == '\r' || *t == '\0')) continue; - - crcdec = NULL; - crclen = 0; - if (rpmBase64Decode(crcenc, (void **)&crcdec, &crclen) != 0 || crclen != 3) { - crcdec = _free(crcdec); - ec = PGPARMOR_ERR_CRC_DECODE; - goto exit; - } - crcpkt = pgpGrab(crcdec, crclen); - crcdec = _free(crcdec); - dec = NULL; - declen = 0; - if (rpmBase64Decode(enc, (void **)&dec, &declen) != 0) { - ec = PGPARMOR_ERR_BODY_DECODE; - goto exit; - } - crc = pgpCRC(dec, declen); - if (crcpkt != crc) { - ec = PGPARMOR_ERR_CRC_CHECK; - _free(dec); - goto exit; - } - if (pkt) - *pkt = dec; - else - _free(dec); - if (pktlen) *pktlen = declen; - ec = PGPARMOR_PUBKEY; /* XXX ASCII Pubkeys only, please. */ - goto exit; - break; - } - } - ec = PGPARMOR_NONE; - -exit: - return ec; -} - - -pgpArmor pgpParsePkts(const char *armor, uint8_t ** pkt, size_t * pktlen) -{ - pgpArmor ec = PGPARMOR_ERR_NO_BEGIN_PGP; /* XXX assume failure */ - if (armor && strlen(armor) > 0) { - uint8_t *b = (uint8_t*) xstrdup(armor); - ec = decodePkts(b, pkt, pktlen); - free(b); - } - return ec; -} - -int pgpPubKeyCertLen(const uint8_t *pkts, size_t pktslen, size_t *certlen) -{ - const uint8_t *p = pkts; - const uint8_t *pend = pkts + pktslen; - struct pgpPkt pkt; - - while (p < pend) { - if (decodePkt(p, (pend - p), &pkt)) - return -1; - - if (pkt.tag == PGPTAG_PUBLIC_KEY && pkts != p) { - *certlen = p - pkts; - return 0; - } - - p += (pkt.body - pkt.head) + pkt.blen; - } - - *certlen = pktslen; - - return 0; -} - -char * pgpArmorWrap(int atype, const unsigned char * s, size_t ns) -{ - char *buf = NULL, *val = NULL; - char *enc = rpmBase64Encode(s, ns, -1); - char *crc = rpmBase64CRC(s, ns); - const char *valstr = pgpValString(PGPVAL_ARMORBLOCK, atype); - - if (crc != NULL && enc != NULL) { - rasprintf(&buf, "%s=%s", enc, crc); - } - free(crc); - free(enc); - - rasprintf(&val, "-----BEGIN PGP %s-----\nVersion: rpm-" VERSION"\n\n" - "%s\n-----END PGP %s-----\n", - valstr, buf != NULL ? buf : "", valstr); - - free(buf); - return val; -} - -rpmRC pgpPubKeyLint(const uint8_t *pkts, size_t pktslen, char **explanation) -{ - *explanation = NULL; - return RPMRC_OK; -} diff --git a/rpmio/rpmpgp_legacy/rpmpgp_internal.h b/rpmio/rpmpgp_legacy/rpmpgp_internal.h deleted file mode 100644 index 5e09347719..0000000000 --- a/rpmio/rpmpgp_legacy/rpmpgp_internal.h +++ /dev/null @@ -1,50 +0,0 @@ -#ifndef _RPMPGP_INTERNAL_H -#define _RPMPGP_INTERNAL_H - -#include - -typedef struct pgpDigAlg_s * pgpDigAlg; - -typedef int (*setmpifunc)(pgpDigAlg digp, int num, const uint8_t *p); -typedef int (*verifyfunc)(pgpDigAlg pgpkey, pgpDigAlg pgpsig, - uint8_t *hash, size_t hashlen, int hash_algo); -typedef void (*freefunc)(pgpDigAlg digp); - -struct pgpDigAlg_s { - setmpifunc setmpi; - verifyfunc verify; - freefunc free; - int curve; - int mpis; - void *data; /*!< algorithm specific private data */ -}; - -pgpDigAlg pgpPubkeyNew(int algo, int curve); - -pgpDigAlg pgpSignatureNew(int algo); - -pgpDigAlg pgpDigAlgFree(pgpDigAlg alg); - -/** \ingroup rpmpgp - * Return no. of bits in a multiprecision integer. - * @param p pointer to multiprecision integer - * @return no. of bits - */ -static inline -unsigned int pgpMpiBits(const uint8_t *p) -{ - return ((p[0] << 8) | p[1]); -} - -/** \ingroup rpmpgp - * Return no. of bytes in a multiprecision integer. - * @param p pointer to multiprecision integer - * @return no. of bytes - */ -static inline -size_t pgpMpiLen(const uint8_t *p) -{ - return (2 + ((pgpMpiBits(p)+7)>>3)); -} - -#endif /* _RPMPGP_INTERNAL_H */