pax_global_header00006660000000000000000000000064147624070260014522gustar00rootroot0000000000000052 comment=be74bd56296ca6b9e0d7fad5f963d46534e9afe0 crypto-config-0.7.4/000077500000000000000000000000001476240702600143155ustar00rootroot00000000000000crypto-config-0.7.4/.gitignore000066400000000000000000000000711476240702600163030ustar00rootroot00000000000000*~ *.sw[po] /target/ /Cargo.* src/main.rs debian/files crypto-config-0.7.4/CHANGELOG.md000066400000000000000000000017011476240702600161250ustar00rootroot00000000000000# Changelog ## [0.7.4] - 2025-03-06 ### Updated/added - Add `doc/lxd-cloud-config` to set up a container which immediately has the right profile applied - Provide an example profile for `exim` ### Removed - Drop `crypto-config-hijack.sh` which is less needed now that changes have made their way in `openssl` and `gnutls` ### Fixed - Dpkg trigger needs to be set on `/usr/share/crypto-config/profiles`, not anywhere in `/etc/`; moreover the trigger must not be made crucial - `dh_install` dropped `profiles/default/openssl.conf.d` which was empty and therefore made `crypto-config` not consider anything openssl - Bad parsing of the parent profile with `metadata.json` - Manpage was missing ### Contributors and reviewers Thanks @waveform and @utkarsh2102 ## [0.7.3] - 2025-02-21 _Initial release._ [0.7.4] https://github.com/canonical/crypto-config/releases/tag/v0.7.4 [0.7.3] https://github.com/canonical/crypto-config/releases/tag/v0.7.3 crypto-config-0.7.4/COPYING000066400000000000000000001045131476240702600153540ustar00rootroot00000000000000 GNU GENERAL PUBLIC LICENSE Version 3, 29 June 2007 Copyright (C) 2007 Free Software Foundation, Inc. Everyone is permitted to copy and distribute verbatim copies of this license document, but changing it is not allowed. Preamble The GNU General Public License is a free, copyleft license for software and other kinds of works. The licenses for most software and other practical works are designed to take away your freedom to share and change the works. By contrast, the GNU General Public License is intended to guarantee your freedom to share and change all versions of a program--to make sure it remains free software for all its users. We, the Free Software Foundation, use the GNU General Public License for most of our software; it applies also to any other work released this way by its authors. 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 them 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 prevent others from denying you these rights or asking you to surrender the rights. Therefore, you have certain responsibilities if you distribute copies of the software, or if you modify it: responsibilities to respect the freedom of others. For example, if you distribute copies of such a program, whether gratis or for a fee, you must pass on to the recipients the same freedoms that you received. 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. Developers that use the GNU GPL protect your rights with two steps: (1) assert copyright on the software, and (2) offer you this License giving you legal permission to copy, distribute and/or modify it. For the developers' and authors' protection, the GPL clearly explains that there is no warranty for this free software. For both users' and authors' sake, the GPL requires that modified versions be marked as changed, so that their problems will not be attributed erroneously to authors of previous versions. Some devices are designed to deny users access to install or run modified versions of the software inside them, although the manufacturer can do so. This is fundamentally incompatible with the aim of protecting users' freedom to change the software. The systematic pattern of such abuse occurs in the area of products for individuals to use, which is precisely where it is most unacceptable. Therefore, we have designed this version of the GPL to prohibit the practice for those products. If such problems arise substantially in other domains, we stand ready to extend this provision to those domains in future versions of the GPL, as needed to protect the freedom of users. Finally, every program is threatened constantly by software patents. States should not allow patents to restrict development and use of software on general-purpose computers, but in those that do, we wish to avoid the special danger that patents applied to a free program could make it effectively proprietary. To prevent this, the GPL assures that patents cannot be used to render the program non-free. The precise terms and conditions for copying, distribution and modification follow. TERMS AND CONDITIONS 0. Definitions. "This License" refers to version 3 of the GNU General Public License. "Copyright" also means copyright-like laws that apply to other kinds of works, such as semiconductor masks. "The Program" refers to any copyrightable work licensed under this License. Each licensee is addressed as "you". "Licensees" and "recipients" may be individuals or organizations. To "modify" a work means to copy from or adapt all or part of the work in a fashion requiring copyright permission, other than the making of an exact copy. The resulting work is called a "modified version" of the earlier work or a work "based on" the earlier work. A "covered work" means either the unmodified Program or a work based on the Program. To "propagate" a work means to do anything with it that, without permission, would make you directly or secondarily liable for infringement under applicable copyright law, except executing it on a computer or modifying a private copy. Propagation includes copying, distribution (with or without modification), making available to the public, and in some countries other activities as well. To "convey" a work means any kind of propagation that enables other parties to make or receive copies. Mere interaction with a user through a computer network, with no transfer of a copy, is not conveying. An interactive user interface displays "Appropriate Legal Notices" to the extent that it includes a convenient and prominently visible feature that (1) displays an appropriate copyright notice, and (2) tells the user that there is no warranty for the work (except to the extent that warranties are provided), that licensees may convey the work under this License, and how to view a copy of this License. If the interface presents a list of user commands or options, such as a menu, a prominent item in the list meets this criterion. 1. Source Code. The "source code" for a work means the preferred form of the work for making modifications to it. "Object code" means any non-source form of a work. A "Standard Interface" means an interface that either is an official standard defined by a recognized standards body, or, in the case of interfaces specified for a particular programming language, one that is widely used among developers working in that language. The "System Libraries" of an executable work include anything, other than the work as a whole, that (a) is included in the normal form of packaging a Major Component, but which is not part of that Major Component, and (b) serves only to enable use of the work with that Major Component, or to implement a Standard Interface for which an implementation is available to the public in source code form. A "Major Component", in this context, means a major essential component (kernel, window system, and so on) of the specific operating system (if any) on which the executable work runs, or a compiler used to produce the work, or an object code interpreter used to run it. The "Corresponding Source" for a work in object code form means all the source code needed to generate, install, and (for an executable work) run the object code and to modify the work, including scripts to control those activities. However, it does not include the work's System Libraries, or general-purpose tools or generally available free programs which are used unmodified in performing those activities but which are not part of the work. For example, Corresponding Source includes interface definition files associated with source files for the work, and the source code for shared libraries and dynamically linked subprograms that the work is specifically designed to require, such as by intimate data communication or control flow between those subprograms and other parts of the work. The Corresponding Source need not include anything that users can regenerate automatically from other parts of the Corresponding Source. The Corresponding Source for a work in source code form is that same work. 2. Basic Permissions. All rights granted under this License are granted for the term of copyright on the Program, and are irrevocable provided the stated conditions are met. This License explicitly affirms your unlimited permission to run the unmodified Program. The output from running a covered work is covered by this License only if the output, given its content, constitutes a covered work. This License acknowledges your rights of fair use or other equivalent, as provided by copyright law. You may make, run and propagate covered works that you do not convey, without conditions so long as your license otherwise remains in force. You may convey covered works to others for the sole purpose of having them make modifications exclusively for you, or provide you with facilities for running those works, provided that you comply with the terms of this License in conveying all material for which you do not control copyright. Those thus making or running the covered works for you must do so exclusively on your behalf, under your direction and control, on terms that prohibit them from making any copies of your copyrighted material outside their relationship with you. Conveying under any other circumstances is permitted solely under the conditions stated below. Sublicensing is not allowed; section 10 makes it unnecessary. 3. Protecting Users' Legal Rights From Anti-Circumvention Law. No covered work shall be deemed part of an effective technological measure under any applicable law fulfilling obligations under article 11 of the WIPO copyright treaty adopted on 20 December 1996, or similar laws prohibiting or restricting circumvention of such measures. When you convey a covered work, you waive any legal power to forbid circumvention of technological measures to the extent such circumvention is effected by exercising rights under this License with respect to the covered work, and you disclaim any intention to limit operation or modification of the work as a means of enforcing, against the work's users, your or third parties' legal rights to forbid circumvention of technological measures. 4. Conveying Verbatim Copies. You may convey 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; keep intact all notices stating that this License and any non-permissive terms added in accord with section 7 apply to the code; keep intact all notices of the absence of any warranty; and give all recipients a copy of this License along with the Program. You may charge any price or no price for each copy that you convey, and you may offer support or warranty protection for a fee. 5. Conveying Modified Source Versions. You may convey a work based on the Program, or the modifications to produce it from the Program, in the form of source code under the terms of section 4, provided that you also meet all of these conditions: a) The work must carry prominent notices stating that you modified it, and giving a relevant date. b) The work must carry prominent notices stating that it is released under this License and any conditions added under section 7. This requirement modifies the requirement in section 4 to "keep intact all notices". c) You must license the entire work, as a whole, under this License to anyone who comes into possession of a copy. This License will therefore apply, along with any applicable section 7 additional terms, to the whole of the work, and all its parts, regardless of how they are packaged. This License gives no permission to license the work in any other way, but it does not invalidate such permission if you have separately received it. d) If the work has interactive user interfaces, each must display Appropriate Legal Notices; however, if the Program has interactive interfaces that do not display Appropriate Legal Notices, your work need not make them do so. A compilation of a covered work with other separate and independent works, which are not by their nature extensions of the covered work, and which are not combined with it such as to form a larger program, in or on a volume of a storage or distribution medium, is called an "aggregate" if the compilation and its resulting copyright are not used to limit the access or legal rights of the compilation's users beyond what the individual works permit. Inclusion of a covered work in an aggregate does not cause this License to apply to the other parts of the aggregate. 6. Conveying Non-Source Forms. You may convey a covered work in object code form under the terms of sections 4 and 5, provided that you also convey the machine-readable Corresponding Source under the terms of this License, in one of these ways: a) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by the Corresponding Source fixed on a durable physical medium customarily used for software interchange. b) Convey the object code in, or embodied in, a physical product (including a physical distribution medium), accompanied by a written offer, valid for at least three years and valid for as long as you offer spare parts or customer support for that product model, to give anyone who possesses the object code either (1) a copy of the Corresponding Source for all the software in the product that is covered by this License, on a durable physical medium customarily used for software interchange, for a price no more than your reasonable cost of physically performing this conveying of source, or (2) access to copy the Corresponding Source from a network server at no charge. c) Convey individual copies of the object code with a copy of the written offer to provide the Corresponding Source. This alternative is allowed only occasionally and noncommercially, and only if you received the object code with such an offer, in accord with subsection 6b. d) Convey the object code by offering access from a designated place (gratis or for a charge), and offer equivalent access to the Corresponding Source in the same way through the same place at no further charge. You need not require recipients to copy the Corresponding Source along with the object code. If the place to copy the object code is a network server, the Corresponding Source may be on a different server (operated by you or a third party) that supports equivalent copying facilities, provided you maintain clear directions next to the object code saying where to find the Corresponding Source. Regardless of what server hosts the Corresponding Source, you remain obligated to ensure that it is available for as long as needed to satisfy these requirements. e) Convey the object code using peer-to-peer transmission, provided you inform other peers where the object code and Corresponding Source of the work are being offered to the general public at no charge under subsection 6d. A separable portion of the object code, whose source code is excluded from the Corresponding Source as a System Library, need not be included in conveying the object code work. A "User Product" is either (1) a "consumer product", which means any tangible personal property which is normally used for personal, family, or household purposes, or (2) anything designed or sold for incorporation into a dwelling. In determining whether a product is a consumer product, doubtful cases shall be resolved in favor of coverage. For a particular product received by a particular user, "normally used" refers to a typical or common use of that class of product, regardless of the status of the particular user or of the way in which the particular user actually uses, or expects or is expected to use, the product. A product is a consumer product regardless of whether the product has substantial commercial, industrial or non-consumer uses, unless such uses represent the only significant mode of use of the product. "Installation Information" for a User Product means any methods, procedures, authorization keys, or other information required to install and execute modified versions of a covered work in that User Product from a modified version of its Corresponding Source. The information must suffice to ensure that the continued functioning of the modified object code is in no case prevented or interfered with solely because modification has been made. If you convey an object code work under this section in, or with, or specifically for use in, a User Product, and the conveying occurs as part of a transaction in which the right of possession and use of the User Product is transferred to the recipient in perpetuity or for a fixed term (regardless of how the transaction is characterized), the Corresponding Source conveyed under this section must be accompanied by the Installation Information. But this requirement does not apply if neither you nor any third party retains the ability to install modified object code on the User Product (for example, the work has been installed in ROM). The requirement to provide Installation Information does not include a requirement to continue to provide support service, warranty, or updates for a work that has been modified or installed by the recipient, or for the User Product in which it has been modified or installed. Access to a network may be denied when the modification itself materially and adversely affects the operation of the network or violates the rules and protocols for communication across the network. Corresponding Source conveyed, and Installation Information provided, in accord with this section must be in a format that is publicly documented (and with an implementation available to the public in source code form), and must require no special password or key for unpacking, reading or copying. 7. Additional Terms. "Additional permissions" are terms that supplement the terms of this License by making exceptions from one or more of its conditions. Additional permissions that are applicable to the entire Program shall be treated as though they were included in this License, to the extent that they are valid under applicable law. If additional permissions apply only to part of the Program, that part may be used separately under those permissions, but the entire Program remains governed by this License without regard to the additional permissions. When you convey a copy of a covered work, you may at your option remove any additional permissions from that copy, or from any part of it. (Additional permissions may be written to require their own removal in certain cases when you modify the work.) You may place additional permissions on material, added by you to a covered work, for which you have or can give appropriate copyright permission. Notwithstanding any other provision of this License, for material you add to a covered work, you may (if authorized by the copyright holders of that material) supplement the terms of this License with terms: a) Disclaiming warranty or limiting liability differently from the terms of sections 15 and 16 of this License; or b) Requiring preservation of specified reasonable legal notices or author attributions in that material or in the Appropriate Legal Notices displayed by works containing it; or c) Prohibiting misrepresentation of the origin of that material, or requiring that modified versions of such material be marked in reasonable ways as different from the original version; or d) Limiting the use for publicity purposes of names of licensors or authors of the material; or e) Declining to grant rights under trademark law for use of some trade names, trademarks, or service marks; or f) Requiring indemnification of licensors and authors of that material by anyone who conveys the material (or modified versions of it) with contractual assumptions of liability to the recipient, for any liability that these contractual assumptions directly impose on those licensors and authors. All other non-permissive additional terms are considered "further restrictions" within the meaning of section 10. If the Program as you received it, or any part of it, contains a notice stating that it is governed by this License along with a term that is a further restriction, you may remove that term. If a license document contains a further restriction but permits relicensing or conveying under this License, you may add to a covered work material governed by the terms of that license document, provided that the further restriction does not survive such relicensing or conveying. If you add terms to a covered work in accord with this section, you must place, in the relevant source files, a statement of the additional terms that apply to those files, or a notice indicating where to find the applicable terms. Additional terms, permissive or non-permissive, may be stated in the form of a separately written license, or stated as exceptions; the above requirements apply either way. 8. Termination. You may not propagate or modify a covered work except as expressly provided under this License. Any attempt otherwise to propagate or modify it is void, and will automatically terminate your rights under this License (including any patent licenses granted under the third paragraph of section 11). However, if you cease all violation of this License, then your license from a particular copyright holder is reinstated (a) provisionally, unless and until the copyright holder explicitly and finally terminates your license, and (b) permanently, if the copyright holder fails to notify you of the violation by some reasonable means prior to 60 days after the cessation. Moreover, your license from a particular copyright holder is reinstated permanently if the copyright holder notifies you of the violation by some reasonable means, this is the first time you have received notice of violation of this License (for any work) from that copyright holder, and you cure the violation prior to 30 days after your receipt of the notice. Termination of your rights under this section does not terminate the licenses of parties who have received copies or rights from you under this License. If your rights have been terminated and not permanently reinstated, you do not qualify to receive new licenses for the same material under section 10. 9. Acceptance Not Required for Having Copies. You are not required to accept this License in order to receive or run a copy of the Program. Ancillary propagation of a covered work occurring solely as a consequence of using peer-to-peer transmission to receive a copy likewise does not require acceptance. However, nothing other than this License grants you permission to propagate or modify any covered work. These actions infringe copyright if you do not accept this License. Therefore, by modifying or propagating a covered work, you indicate your acceptance of this License to do so. 10. Automatic Licensing of Downstream Recipients. Each time you convey a covered work, the recipient automatically receives a license from the original licensors, to run, modify and propagate that work, subject to this License. You are not responsible for enforcing compliance by third parties with this License. An "entity transaction" is a transaction transferring control of an organization, or substantially all assets of one, or subdividing an organization, or merging organizations. If propagation of a covered work results from an entity transaction, each party to that transaction who receives a copy of the work also receives whatever licenses to the work the party's predecessor in interest had or could give under the previous paragraph, plus a right to possession of the Corresponding Source of the work from the predecessor in interest, if the predecessor has it or can get it with reasonable efforts. You may not impose any further restrictions on the exercise of the rights granted or affirmed under this License. For example, you may not impose a license fee, royalty, or other charge for exercise of rights granted under this License, and you may not initiate litigation (including a cross-claim or counterclaim in a lawsuit) alleging that any patent claim is infringed by making, using, selling, offering for sale, or importing the Program or any portion of it. 11. Patents. A "contributor" is a copyright holder who authorizes use under this License of the Program or a work on which the Program is based. The work thus licensed is called the contributor's "contributor version". A contributor's "essential patent claims" are all patent claims owned or controlled by the contributor, whether already acquired or hereafter acquired, that would be infringed by some manner, permitted by this License, of making, using, or selling its contributor version, but do not include claims that would be infringed only as a consequence of further modification of the contributor version. For purposes of this definition, "control" includes the right to grant patent sublicenses in a manner consistent with the requirements of this License. Each contributor grants you a non-exclusive, worldwide, royalty-free patent license under the contributor's essential patent claims, to make, use, sell, offer for sale, import and otherwise run, modify and propagate the contents of its contributor version. In the following three paragraphs, a "patent license" is any express agreement or commitment, however denominated, not to enforce a patent (such as an express permission to practice a patent or covenant not to sue for patent infringement). To "grant" such a patent license to a party means to make such an agreement or commitment not to enforce a patent against the party. If you convey a covered work, knowingly relying on a patent license, and the Corresponding Source of the work is not available for anyone to copy, free of charge and under the terms of this License, through a publicly available network server or other readily accessible means, then you must either (1) cause the Corresponding Source to be so available, or (2) arrange to deprive yourself of the benefit of the patent license for this particular work, or (3) arrange, in a manner consistent with the requirements of this License, to extend the patent license to downstream recipients. "Knowingly relying" means you have actual knowledge that, but for the patent license, your conveying the covered work in a country, or your recipient's use of the covered work in a country, would infringe one or more identifiable patents in that country that you have reason to believe are valid. If, pursuant to or in connection with a single transaction or arrangement, you convey, or propagate by procuring conveyance of, a covered work, and grant a patent license to some of the parties receiving the covered work authorizing them to use, propagate, modify or convey a specific copy of the covered work, then the patent license you grant is automatically extended to all recipients of the covered work and works based on it. A patent license is "discriminatory" if it does not include within the scope of its coverage, prohibits the exercise of, or is conditioned on the non-exercise of one or more of the rights that are specifically granted under this License. You may not convey a covered work if you are a party to an arrangement with a third party that is in the business of distributing software, under which you make payment to the third party based on the extent of your activity of conveying the work, and under which the third party grants, to any of the parties who would receive the covered work from you, a discriminatory patent license (a) in connection with copies of the covered work conveyed by you (or copies made from those copies), or (b) primarily for and in connection with specific products or compilations that contain the covered work, unless you entered into that arrangement, or that patent license was granted, prior to 28 March 2007. Nothing in this License shall be construed as excluding or limiting any implied license or other defenses to infringement that may otherwise be available to you under applicable patent law. 12. No Surrender of Others' Freedom. If 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 convey a covered work so as to satisfy simultaneously your obligations under this License and any other pertinent obligations, then as a consequence you may not convey it at all. For example, if you agree to terms that obligate you to collect a royalty for further conveying from those to whom you convey the Program, the only way you could satisfy both those terms and this License would be to refrain entirely from conveying the Program. 13. Use with the GNU Affero General Public License. Notwithstanding any other provision of this License, you have permission to link or combine any covered work with a work licensed under version 3 of the GNU Affero General Public License into a single combined work, and to convey the resulting work. The terms of this License will continue to apply to the part which is the covered work, but the special requirements of the GNU Affero General Public License, section 13, concerning interaction through a network will apply to the combination as such. 14. Revised Versions of this License. The Free Software Foundation may publish revised and/or new versions of the GNU 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 that a certain numbered version of the GNU General Public License "or any later version" applies to it, you have the option of following the terms and conditions either of that numbered version or of any later version published by the Free Software Foundation. If the Program does not specify a version number of the GNU General Public License, you may choose any version ever published by the Free Software Foundation. If the Program specifies that a proxy can decide which future versions of the GNU General Public License can be used, that proxy's public statement of acceptance of a version permanently authorizes you to choose that version for the Program. Later license versions may give you additional or different permissions. However, no additional obligations are imposed on any author or copyright holder as a result of your choosing to follow a later version. 15. Disclaimer of Warranty. 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. 16. Limitation of Liability. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MODIFIES AND/OR CONVEYS 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. 17. Interpretation of Sections 15 and 16. If the disclaimer of warranty and limitation of liability provided above cannot be given local legal effect according to their terms, reviewing courts shall apply local law that most closely approximates an absolute waiver of all civil liability in connection with the Program, unless a warranty or assumption of liability accompanies a copy of the Program in return for a fee. 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 state 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 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 3 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, see . Also add information on how to contact you by electronic and paper mail. If the program does terminal interaction, make it output a short notice like this when it starts in an interactive mode: Copyright (C) This program 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, your program's commands might be different; for a GUI interface, you would use an "about box". You should also get your employer (if you work as a programmer) or school, if any, to sign a "copyright disclaimer" for the program, if necessary. For more information on this, and how to apply and follow the GNU GPL, see . The GNU 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 Lesser General Public License instead of this License. But first, please read . crypto-config-0.7.4/Makefile000066400000000000000000000001741476240702600157570ustar00rootroot00000000000000all: manpages %.1: %.1.adoc asciidoctor -b manpage "$?" manpages: man/crypto-config.1 clean: rm -f man/crypto-config.1 crypto-config-0.7.4/README.md000066400000000000000000000205401476240702600155750ustar00rootroot00000000000000# Crypto-config A configuration management framework for cryptography using system-wide profiles that are switched atomically. It is gradually being rolled out in Ubuntu. This repository contains the framework. Profile data is to be stored directly inside each package. As an exception during early days, this repository may also contain profile data in order to avoid a chicken-and-egg situation. # Table of contents - [Example](#example) - [Usecases](#usecases) - [Hardening and compliance](#hardening-and-compliance) - [Large-scale environments](#large-scale-environments) - [Best-practices tracking](#best-practices-tracking) - [Sources of the configuration with `crypto-config`](#sources-of-the-configuration-with-crypto-config) - [What profiles are](#what-profiles-are) - [Usage of /usr/bin/crypto-config](#usage-of-usrbincrypto-config) - [get](#get) - [status](#status) - [switch \](#switch-profile) - [Implementation and porting](#implementation-and-porting) - [Profile storage and switch](#profile-storage-and-switch) - [Inheritance and generation of runtime data](#inheritance-and-generation-of-runtime-data) - [Making software read from `crypto-config` profiles](#making-software-read-from-crypto-config-profiles) - [Specification](#specification) - [Bug reports](#bug-reports) - [License](#license) ## Example Consider two profiles: `default` and `future`. The `future` one disables TLS < 1.3 and RSA < 4096. Configure an `nginx` server with TLS and use `sslscan` to check its configuration; the output will contain the following: # sslscan 127.0.0.1 ... TLSv1.2 enabled TLSv1.3 enabled Switch to the `future` profile from `crypto-config: crypto-config switch future Restart `nginx` and use `sslscan` again. systemctl restart nginx sslscan 127.0.0.1 ... TLSv1.2 disabled TLSv1.3 enabled ## Usecases ### Hardening and compliance Distributions need to find the balance between compatibility and security. Some legacy systems do not understand newer protocols and algorithms. Crypto-config profiles can be made for hardening or compliance purposes. In addition, it is possible to derive customized profiles for these in order to re-enable a given algorithm if needed (for instance because you still need to keep compatibility with that old box you can't get rid of). Since `crypto-config` profiles use inheritance and are stored in unified locations, customisations are easier to spot and maintain over extended periods of time. ### Large-scale environments System administrators for large networks will probably appreciate the ability to create unified configuration for all machines. Since these stocks are most likely heterogeneous and cannot be all upgraded at once, it can be useful to design a profile and do a progressive roll-out across machines. Moreover, profiles with modern configuration options can be customised to keep some legacy algorithms enabled until not needed anymore. ### Best-practices tracking After release, Ubuntu versions strive to preserve compatibility. This typically means not disabling a cryptographic algorithm as that would prevent data exchange in some situations. This can be at odds with security when an algorithm is found to be broken or almost broken. A proposal for Ubuntu is to keep the `default` profile unchanged over time. The experience of most users would therefore be unchanged. However, other profiles may be updated. As such, profiles such as `modern` could be updated over time to avoid actually becoming a `legacy` profile after a few years. In addition, changes to the profiles could be staged in dedicated profiles such as `modern-incoming`. Having too many profiles would be detrimental but incoming variants would carry differences only for maybe six months or so. ## Sources of the configuration with `crypto-config` There are two ways a program such as `nginx` is configured in practice. The paths below refer to the files used with `crypto-config` specifically. First, through its own configuration: nginx ⬇️ /etc/nginx/nginx.conf ⬇️ /etc/nginx/conf.d/crypto-config.conf ⬇️ /var/lib/crypto-config/profiles/current/nginx.conf.d/*.conf ⬇️ /var/lib/crypto-config/profiles/current/nginx.conf.d/ssl.conf But some of its features are also impacted by the configuration of its dependencies: nginx ⬇️ /etc/ssl/openssl.cnf ⬇️ /var/lib/crypto-config/profiles/current/openssl.conf.d ⬇️ /var/lib/crypto-config/profiles/current/openssl.conf.d/seclevel.cnf ## What profiles are Crypto-config profiles are made of drop-in files and configuration fragments. You can think of a profile as a subset of configuration files on your system, and choosing a profile as atomically switching these to alternative ones. Distributions should come up with a list of profiles and the intent for each of them. Typical examples include `default`, `legacy` and `future`: - `default` would match what is already being done at the moment, - `legacy` tweaks `default` to increase compatibility with legacy systems, - `future` tweaks `default` to increase security and uses settings that are expected to become the default ones in the future. The core goal is to have various software configured in a consistent and meaningful way. For instance, a profile that disables a protocol for openssl should disable it for gnutls too. However, it is also understandable that an algorithm is disabled for HTTPS servers but enabled for SMTP ones because they live in two different ecosystems. ## Usage of /usr/bin/crypto-config The crypto-config binary currently accepts three commands: `get`, `status` and `switch `'. ### get Return the profile currently in use. ### status Show the profile currently in use. May show more in the future. This is meant for interactive use rather than for scripting. ### switch \ Use this profile. ## Implementation and porting ### Profile storage and switch The profiles are stored in `/var/lib/crypto-config/profiles`. In this directory there is also a symlink called `current` which points to the chosen profile. The profile switch is the atomic change of the symlink target. ### Inheritance and generation of runtime data It is possible to skip the configuration for some software when creating a profile: it will be inherited from the profile's parent through an inheritance mechanism. Packages install profile data under `/usr/share/crypto-config/profiles/`. After installation, a short (and idempotent) program fills in the skipped data using based on the inheritance relationship. The result is then stored in `/var/lib/crypto-config/profiles` and is ready to be used by software. ### Making software read from `crypto-config` profiles There are dozens, if not hundreds, of different configuration systems. There is therefore no single way to make software read part of its configuration from `crypto-config`: it depends on each software. Luckily, nowadays many pieces of software handle `include`-style directives and drop-ins. As an example, for openssl, the following has been added at the end of `/etc/ssl/openssl.cnf`: .include /var/lib/crypto-config/profiles/current/openssl.conf.d Of course, this will only have an actual effect when there is something in that directory. It's more convenient to not fail when the target directory or file does not exist. For instance, enabling `crypto-config` for nginx uses `/etc/nginx/conf.d/crypto-config.conf` which contains the following: include /var/lib/crypto-config/profiles/current/nginx.conf.d/*.conf; Nginx refuses to start if it is instructed to `include` a non-existing file for its configuration. However, if there is a wildcard in the path, it accepts that there is no matching file. These small changes to configuration are to be done by package maintainers and as they should make the best judgement. Similarly, packagers provide configuration snippets for the various profiles that it makes sense for them to support directly. ## Specification The full specification lives on [discourse.ubuntu.com](https://discourse.ubuntu.com/t/spec-crypto-config-a-framework-to-manage-crypto-related-configurations-system-wide/54265/1) and is also [copied in this repository](docs/crypto-config-specification.md). ## Bug reports Please file bug reports in [Launchpad](https://bugs.launchpad.net/crypto-config). ## License Crypto-config is licensed under the [GPLv3](COPYING). crypto-config-0.7.4/debian/000077500000000000000000000000001476240702600155375ustar00rootroot00000000000000crypto-config-0.7.4/debian/changelog000066400000000000000000000005241476240702600174120ustar00rootroot00000000000000crypto-config (0.7.4-0ubuntu1) plucky; urgency=medium * New upstream release -- Adrien Nader Thu, 06 Mar 2025 21:40:39 +0100 crypto-config (0.7.3-0ubuntu1) plucky; urgency=medium * Initial upload to Ubuntu (LP: #2098879) -- Adrien Nader Fri, 21 Feb 2025 15:32:44 +0100 crypto-config-0.7.4/debian/control000066400000000000000000000016321476240702600171440ustar00rootroot00000000000000Source: crypto-config Section: admin Priority: optional Maintainer: Ubuntu Developers XSBC-Original-Maintainer: Adrien Nader Rules-Requires-Root: no Build-Depends: debhelper-compat (= 13), asciidoctor, Standards-Version: 4.7.0 Homepage: https://www.github.com/canonical/crypto-config Vcs-Browser: https://www.github.com/canonical/crypto-config Vcs-Git: https://www.github.com/canonical/crypto-config.git Package: crypto-config Architecture: all Depends: ${shlibs:Depends}, ${misc:Depends}, Description: Atomic management of related cryptographic options Crypto-config enables managing related configuration options in an atomic manner. It makes it possible to enable or disable an element across all software enrolled in the scheme. It is meant to offer system administrators a way to filter cryptographic algorithms and key sizes system-wide. crypto-config-0.7.4/debian/copyright000066400000000000000000000010751476240702600174750ustar00rootroot00000000000000Format: https://www.debian.org/doc/packaging-manuals/copyright-format/1.0/ Source: https://www.github.com/canonical/crypto-config Upstream-Name: crypto-config Files: * Copyright: 2023-2024 Canonical Ltd. License: GPL-3 License: GPL-3 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, version 3 of the License. . On Debian systems, the complete text of the GNU General Public License version 3 can be found in "/usr/share/common-licenses/GPL-3". crypto-config-0.7.4/debian/crypto-config.install000066400000000000000000000001101476240702600217020ustar00rootroot00000000000000profiles/* usr/share/crypto-config/profiles/ src/crypto-config usr/bin/ crypto-config-0.7.4/debian/crypto-config.manpages000066400000000000000000000000241476240702600220330ustar00rootroot00000000000000man/crypto-config.1 crypto-config-0.7.4/debian/crypto-config.postinst000077500000000000000000000016601476240702600221350ustar00rootroot00000000000000#!/bin/sh # # Copyright (C) 2023-2024 Canonical, Ltd. # Author: Adrien Nader # # 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; version 3. # # 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, see . # This script is meant to be used when the postinst script is called with $1 # set to 'configure' or 'triggered' set -e set -u case "$1" in triggered|configure) shift crypto-config generate-runtime-profiles ;; *) ;; esac #DEBHELPER# exit 0 crypto-config-0.7.4/debian/crypto-config.triggers000066400000000000000000000000631476240702600220710ustar00rootroot00000000000000interest-noawait /usr/share/crypto-config/profiles crypto-config-0.7.4/debian/rules000077500000000000000000000000661476240702600166210ustar00rootroot00000000000000#!/usr/bin/make -f #export DH_VERBOSE = 1 %: dh $@ crypto-config-0.7.4/debian/source/000077500000000000000000000000001476240702600170375ustar00rootroot00000000000000crypto-config-0.7.4/debian/source/format000066400000000000000000000000141476240702600202450ustar00rootroot000000000000003.0 (quilt) crypto-config-0.7.4/debian/source/options000066400000000000000000000001051476240702600204510ustar00rootroot00000000000000extend-diff-ignore = "^(target/.*|Cargo\.(lock|toml)|src/main\.rs)$" crypto-config-0.7.4/debian/upstream/000077500000000000000000000000001476240702600173775ustar00rootroot00000000000000crypto-config-0.7.4/debian/upstream/signing-key.asc000066400000000000000000000124521476240702600223170ustar00rootroot00000000000000-----BEGIN PGP PUBLIC KEY BLOCK----- mQINBGNJF2wBEADfyHVVZ1ed+I79KMOyynwj8rx0zTSq6pJmCQKLNBgGTNOW2k3x jQtatfl9vQTthw7qpeNlM1257oS2dkKViYBn1NSv0Dr6JWJY4kha05OkRsaOQV7c ETxyWcyZUv/RfVwIznjXMSrNNaGOlZkBMoP2cIVw2drvmWae0i3BLPoAyyjckDlb FwKDl2Ry2LTZ82Uy29aI5kCmN3MyWZ+vX5WbjiKod4N/2WNFdgNMUYm/oUsG5/EK rDkO+tXYRB6uICKokH/7VTM0TRIukCEI5f1TNvT1efJFc8LQgVMykRhRSUWOMRcC Qk7/1J5LeeBFRhxYeKpzTdx9E1by/83GJPvzuOp0UOmPGT90U1hCg6oBM9SR2DBl iJQYOe7KMz7CnsQNOR+0AqLTbJ0okilXrOJzxfUHWNZVsVjirlnS+1FUElKYpGsK RxA3zq9FGdAXiD2j4B/qjujSqlhp7RuasqLx0g6nYWOUIVYJHjxRuhrSw22VwdNk lxL868tPgGrufutwAspoYY/l9MHVCvWlSswGtU8l8HTt2gU3DdWg/WrJw+5vgSTx /SpyX9EhRDzjp5BhbYGjkUAmzx50S4bqtELgDzqu+Kpty8B/SfQ5wsBldAaMFDpS dgPcu5WkKlPfkJyUHm7UDTlRg3voasQxGR4YqUeSYwGWWAPAW+V2G/SEvwARAQAB tClBZHJpZW4gTmFkZXIgPGFkcmllbi5uYWRlckBjYW5vbmljYWwuY29tPokCVAQT AQoAPhYhBMl9na40BdMtRDMNj3iPbroarWXsBQJjSRdsAhsDBQkHhM4ABQsJCAcC BhUKCQgLAgQWAgMBAh4BAheAAAoJEHiPbroarWXsSWUQAK+qhQ37E3U7AH28aq2e Q7OSHm36rGJ+i6CRHwh+v/jS15ZkGUPE6Hmpbf4IGETmEOTj8WcmwRPOpIDiCP0o hNh12pRvqIcm2ocJx8akewGRv+i86V4dUVyJPp9KTMbujmWvUCiGQISSRBqu5eHM gYBpTfyYMp2nlC+y6p9bRboTrDAFX02pedgkJ7/KjAv2lTSOxpONVW2QRLf/I6NE gG7OsS0srcM+POr1XgrrgZ9KASJKee0uxH/psr454JAbyoPjvnRAOEO4u9fuhI4P o0R1FSoQSGwjCVarSoNw0F98Rvjg8H92qEl3RJ+WOG+usv4z+JeE1ZP/ETi59umJ MS/9X01dbU2LNWB30Lz7gntKFrWfp6PfoZjTcbF7VV7GJisykM83iJYK7VpYU5Th UC0q1a7EI8WSu87QeGirrco2wAozCSqjHo6VqYLfi3AwNCcJ9DCa9n8V0QcfPwju c47MO2PT27C9wmDpCDES8Ofls3HorMeNUkbdRh7H9ZNItOOkKaZLeID3IXqF2rVY giAyw/Jr6j+5EWUXkkAaBAmAwb4YxaM1WSNEPfBCFJZ4uYNO20nbTec2ze6rppXw QpSCZGpbE+bvCEfaxTpfHU1w9BkDe9NqnubzX+L5QFHv+ILXn9sy4oQ55rsSGuxN DA9Zu4cm0C0QbTbucxOPTNMeuQINBGNJF2wBEADElKhyMYRBon0vSGn6C+0fsVKj Iwo87wdQxYLPgBkVDbgOV6jxVhT1dgNc7d7+FV/AgUt7cpWWFmApqa4rVIzIR0Sr VZvXlhXQ0NfOD2UFYIVo2dodxvxzwY1uZXtJaUyihRbUPgq2d/FwJLYf41j0yFue Ytka5CgGrzjlBOdpvd11TVAr4HyFT/VBF3L/xFu8Leli07bXGXscLQdHefe94ZGI NnyG+xGQ7YmyLL7baDsMXXFt80v4NgQR0w1brkuk1UPUeWpxyAdmhZMDFGXuVhdf qWA7PguXsK1ZXkXXsrqSYahRiRg5GCL2sAEHlAC2LEoWZJzmHOt3h7kvJ7qiD/lg 6tLGsNLmpYLM2vIHhIYlv5zfK1panNXFFDib5eTjvmASK9vurUdsi3PVdnxn9LYs N8XI8j+Z00r2jQhH6R6NgIITwobO6tCIAUbCrcXf2wIPnQQ6ePl1id63kbj4SJog xi29ncLDCwZDU5lDO8pR13lJgEdg9fezQibY+u2biaG/NlHswXE0Jm4LUKs29b/W Y5XUWhl4eFqiG/myGC5O74/Nbo1cxbHJLqVrpVAsewd4x/Wg6OLCSw6DXKT3fGcE XhEysIEKajNtP+PFM75VAFldmGx4ebfu50pBmqMiX9HEUnnHCPoHymL/9EF8nY7t kUjrsyhgsZZ7eSuNNQARAQABiQI8BBgBCgAmFiEEyX2drjQF0y1EMw2PeI9uuhqt ZewFAmNJF2wCGwwFCQeEzgAACgkQeI9uuhqtZeyPTg/+Mr2wRaBXID99QeOcG8aT Nrjv5krnTNOqO2gPLeSit45kG1mJJKUjLFVrPGpd5buyN6tplCNeATIQixNeQU1F adWuQJJTXyEE41iU+Sj4ALBlObhBuk6IbVa6UsSSjRh6xp5Z6ldd6Jh3W8e6Uekc 86mrycYZPl3oNr5ACmc7y5fLfa6B4l5i1JCptpExMiTSDjvBPBmqMhvvVrihM3qr fCpJ9e4Ey+S1WyoTdyrmU9PA6THXWL60NsZPTI7kBUAJmBwBLzUEhGfwsZqpv3yE LBac3NuXVRy8Y6lrfaOMqTSbuzEODwF2P/Gov5CWNXvCM8r2sjSrtNe/NzLb8DX0 jadTZxjP/2TyOn832nXbZV2Ah2HJcXleG1vkwswhwOchU1w577XLD70nBUoVJRhe mt8PKry6W3EHLcCF6ZHe+Ij+hM4O4YpvGU5Mh099YUt+IJncdRNA7V7DbFrdi2xw eCT8Sjs8w3BJnFarNsJl5W5EDvvoSHDxMbnUcNH8aEr8HwbfkoOAqTOshGHZZ5s3 E0Zw6qloR2F3NX00zP+VbNMYu0VFvx2y4MzPqbm5ZD6faH2UsMtpbG2Zy18hDehV C++QhTbosjpxxfXD09MEJ/9CY95RgaQkmskeOucxGEdCuOCMKqgHje3/JSLQnuz9 /0D6p5g4tBY9r68jQ3V39x25Ag0EY0kXbAEQAN/IdVVnV534jv0ow7LKfCPyvHTN NKrqkmYJAos0GAZM05baTfGNC1q1+X29BO2HDuql42UzXbnuhLZ2QpWJgGfU1K/Q OvolYljiSFrTk6RGxo5BXtwRPHJZzJlS/9F9XAjOeNcxKs01oY6VmQEyg/ZwhXDZ 2u+ZZp7SLcEs+gDLKNyQOVsXAoOXZHLYtNnzZTLb1ojmQKY3czJZn69flZuOIqh3 g3/ZY0V2A0xRib+hSwbn8QqsOQ761dhEHq4gIqiQf/tVMzRNEi6QIQjl/VM29PV5 8kVzwtCBUzKRGFFJRY4xFwJCTv/Unkt54EVGHFh4qnNN3H0TVvL/zcYk+/O46nRQ 6Y8ZP3RTWEKDqgEz1JHYMGWIlBg57sozPsKexA05H7QCotNsnSiSKVes4nPF9QdY 1lWxWOKuWdL7UVQSUpikawpHEDfOr0UZ0BeIPaPgH+qO6NKqWGntG5qyovHSDqdh Y5QhVgkePFG6GtLDbZXB02SXEvzry0+Aau5+63ACymhhj+X0wdUK9aVKzAa1TyXw dO3aBTcN1aD9asnD7m+BJPH9KnJf0SFEPOOnkGFtgaORQCbPHnRLhuq0QuAPOq74 qm3LwH9J9DnCwGV0BowUOlJ2A9y7laQqU9+QnJQebtQNOVGDe+hqxDEZHhipR5Jj AZZYA8Bb5XYb9IS/ABEBAAGJBHIEGAEKACYWIQTJfZ2uNAXTLUQzDY94j266Gq1l 7AUCY0kXbAIbIgUJB4TOAAJACRB4j266Gq1l7MF0IAQZAQoAHRYhBMl9na40BdMt RDMNj3iPbroarWXsBQJjSRdsAAoJEHiPbroarWXs0RsP+weXoPc6FfyYD1CRqOFd V5TfiHA61JKGQuhiZ4erAdm9UYR26b92ypl8Cuj9Rt8sng9X4DzTHtYSv305Tkd5 xMxy2U/jq0Ldbu6fjBD7rBHcP68umwL5YISG2JGZZzWSoWZIlnTAuaOTFjvBCK+w 2CY6BZtR0VFhEUBXzzfVgWxPBMFXCD7X14qUoU5MKGf4V98xhoE1qItI6Y+bmqUZ 7SDjH+CiwVyW/+5piXxCrua0AJxrlq67pQUsqi4N7eDqiKRFPVZ1aByNOpED2+ZH qHm5RLUw0qFw3AuusMAJFB2kgoNQYiC2ZjUOEgmsPsSNGuybCU6G0KQN3P2g+inn ZTs1JhvKoVa1X1L+sJulEfeVNhA5MGc7jp+aHdaRKZKCMVe44svl0is96qIVPZNV 5R7uqKl+irfIFQ3Bb6NxBQiUEgBB7GEz+jcXNJJ2m906huRNjEGd97awTA0ansz7 3HbNuP+wHbBMXA/ilbcblPPEF569ssvf9qKVNgkzVOCIGOji+b9Ng2k6lFYSBJof Qoe1FnTq4258quq+LtokxIQsgHZZ75VdYwfiJx0odPDraAb7YzCSqJI0wlT+9FkQ umEFy6sjD9H2No9PejX2VLHYUYxnzjX8rnOoLo1EVyb9S3apCi2pl5WHeh8gI+D7 vTwY3qq8NXYGqJsr9iyrukXrFbQP/RtTSEBhbzCNeokh7Zxw7wo2AqU3oXMWn2fK A1xUINlgVlMV6CJbP6uxXRigqwIZ8osnpV/0QNi2ODwvM4eBgFKfZdfm2Mde9QXv Krirawa4DEER9WpnZrJyeMl32SBRJZ5LeJ0XnhiL+ptG+kjH+VP4h2qeFvGhLJKT +4xFvbYaTLSummpk2KWwZbxtyhJqY2WGagW4Z2gAoyWpve67CxXo64tDy4J6Dm39 eimS2ja5wmOFr2BgTzSQaKEggE0gBHMf6OTDWtpHhkgPy3peGw8EZB2GcZLb3scV vRB814/1d6qcC+bQDfhHnkpk2ymwQpR8Z2KuzA/tbP9ePtBWdyEJ2AdWxZLDWbz/ rmwNHxtygzuUk14M4klOIr3VyXapkvsEZDrZGciEil6v68z7bjF8cunvT+HjLr15 j73HmSyzn/4oJ3VwHeOqv48OxN08GrjbQmlSN1OgLHab2GPKcenB/8VxcuRIeiiG xkX7gFldTs0WdNBnzZ4795BPU/sE9GQo2juxpC9O6WeuLK1XCZBgoQ709IQCbcMt Z19gXmy5kRVSvvlE9xajl4sTitJ5rhdvfywd88FJqYJEyiqyZFQCjs5XEhnGEuOi UdKV+vn08xeB8s3OW0IQ3Yju7tV0xz0UhWqFrWusGyC0dr/gAXJ8yjsVnNAXDykn /lnSREL6 =qfNm -----END PGP PUBLIC KEY BLOCK----- crypto-config-0.7.4/debian/watch000066400000000000000000000004001476240702600165620ustar00rootroot00000000000000version=4 # From https://wiki.debian.org/debian/watch#GitHub opts=\ pgpsigurlmangle=s%archive/refs/tags/v(.*)\.tar\.gz%releases/download/v$1/v$1.tar.gz.asc% \ https://github.com/canonical/@PACKAGE@/tags \ (?:.*?/)?v?@ANY_VERSION@@ARCHIVE_EXT@ crypto-config-0.7.4/docs/000077500000000000000000000000001476240702600152455ustar00rootroot00000000000000crypto-config-0.7.4/docs/crypto-config-specification.md000066400000000000000000002237711476240702600232040ustar00rootroot00000000000000NB: the best way to make the display wider to display diagrams better is Firefox' reading mode; hopefully svgbob will soon render ascii art diagrams below | Index | FO104 | | :---: | :---- | | **Title** | crypto-config \- a framework to manage crypto-related configurations system-wide | | **[Status](https://docs.google.com/document/d/1lStJjBGW7lyojgBhxGLUNnliUocYWjAZ1VEbbVduX54/edit?usp=sharing)** | Approved | | **Authors** | [Adrien Nader](mailto:adrien.nader@canonical.com) | | **[Type](https://docs.google.com/document/d/1lStJjBGW7lyojgBhxGLUNnliUocYWjAZ1VEbbVduX54/edit?usp=sharing)** | Standard | | **Created** | 2022-11-17 | | Reviewer | Status | | ----- | ----- | | [Andreas Hasenack](mailto:andreas.hasenack@canonical.com) | Approved Sep 19, 2024 | | [Michael Hudson-Doyle](mailto:michael.hudson@canonical.com) | Approved Aug 16, 2024 | | [Seth Arnold](mailto:seth.arnold@canonical.com) | Approved Oct 15, 2024 | | [Tobias Heider](mailto:tobias.heider@canonical.com) | Approved Sep 10, 2024 | # **Abstract** Cryptography configuration is unique among types of configuration: it may need to be updated multiple times over the lifetime of a system or a cluster while requiring consistency across all installed software. We want to offer a way to choose a system-wide crypto configuration among several consistent and supported alternatives. This specification defines a framework made of tools and policy. The policy affects package building and software behavior. Tools are used for system administration. This specification puts a greater emphasis on policy rather than tools, as the policy will serve as the foundation for the design and implementation of tools in the future. ## **Aside: crypto-what?** In this document we use “crypto” to mean basically anything that gnutls or openssl provide. This includes but is not limited to: cryptography primitives, SSL and TLS implementations, and certificate handling. In addition, we define ‘crypto providers’ which expose crypto APIs and implement protocols and algorithms, and ‘crypto users’ which consume these. A user can also be a provider. # **Table of contents** [Abstract](#p-135705-abstract) -- [Aside: crypto-what?](#p-135705-aside-crypto-what) [Table of contents](#p-135705-table-of-contents) [Forewords](#p-135705-forewords) [Current implementation](#p-135705-current-implementation) [The issues at stake](#p-135705-the-issues-at-stake) -- [Lack of consistent configuration: case study on Mantic Minotaur](#p-135705-lack-of-consistent-configuration-case-study-on-mantic-minotaur) -- [Moving security forward](#p-135705-moving-security-forward) -- [Crypto-config overview](#p-135705-crypto-config-overview) -- [Applicability to non-crypto domains](#p-135705-applicability-to-non-crypto-domains) [State of the art: Fedora’s crypto-policies](#p-135705-state-of-the-art-fedora’s-crypto-policies) [Rationale for a new policy and tools](#p-135705-rationale-for-a-new-policy-and-tools) [User stories](#p-135705-user-stories) -- [Other constraints, motivations and design goals](#p-135705-other-constraints-motivations-and-design-goals) [Specification](#p-135705-specification) -- [Constants used in the specification](#p-135705-constants-used-in-the-specification) -- [In a nutshell](#p-135705-in-a-nutshell) -- [Overview](#p-135705-overview) -- [Policy](#p-135705-policy) -- [Paths](#p-135705-paths) -- [Profiles design](#p-135705-profiles-design) -- [Profile inheritance](#p-135705-profile-inheritance) -- [Packages](#p-135705-packages) -- [User-facing tool](#p-135705-user-facing-tool) -- [Configuration sealing](#p-135705-configuration-sealing) -- [Statically-linked crypto providers](#p-135705-statically-linked-crypto-providers) [Affected packages](#p-135705-affected-packages) -- [Crypto providers](#p-135705-crypto-providers) -- [Crypto users](#p-135705-crypto-users) [Example: usefulness with krb5](#p-135705-example-usefulness-with-krb5) [Known Limitations and Future work](#p-135705-known-limitations-and-future-work) -- [Known Limitations](#p-135705-known-limitations) -- [Future work](#p-135705-future-work) [Further Information](#p-135705-further-information) -- [Annex: bits of security, comparable algorithm strengths, and boiling oceans](#p-135705-annex-bits-of-security-comparable-algorithm-strengths-and-boiling-oceans) -- [Annex: Possible work split](#p-135705-annex-possible-work-split) -- [Annex: relationship with distribution upstreams (Debian) and downstreams (Ubuntu derivatives)](#p-135705-annex-relationship-with-distribution-upstreams-(debian)-and-downstreams-(ubuntu-derivatives)) -- [Annex: Example report following package install or removal](#p-135705-annex-example-report-following-package-install-or-removal) [References](#p-135705-references) # **Forewords** This specification is long. It touches many topics and many pieces of software. Not everything can be explained linearly unfortunately and Google docs is not entirely helpful as it is very limited. That being said, I believe the specification is consistent and the puzzle will become a clear picture by the end of the document. In order to ease reading, I am introducing notes at the beginning of sections. These are not the specification but rather some context around it. They are displayed as follows: | 💡This is an informative text. Color is copied from the venerable dokuwiki "note" plugin which most recent version is hosted at [https://github.com/lpaulsen93/dokuwiki\_note](https://github.com/lpaulsen93/dokuwiki_note) and is released under the GPLv2. The plugin uses round corners but the best I can do with google docs is a 1-cell table with ugly hard corners. | | :---- | It should be noted that this document has been authored in Google Docs. Not all export formats can be used reliably unfortunately: markdown is fine when diagrams and non-docs resources are not used while PDF appears to work for everything but is less convenient to handle. As such, this specification will be exported and published first using the markdown export and a PDF export will also be provided for reference. # **Current implementation** There is already a partial implementation of the specification available. It is hosted on [github.com/canonical/crypto-config](http://github.com/canonical/crypto-config). It contains the integration with `dpkg` using a `post-inst` trigger. It also handles profile inheritance, albeit with the parent being set using a bare text file rather than JSON because the current implementation is a shell script. This is planned to be solved when re-writing the implementation in Rust, which will also feature a more complete UI. # **The issues at stake** NB: A lightning talk on this topic was given at the [Ubuntu Engineering Sprint in Riga in November 2023](https://docs.google.com/presentation/d/1wFuKDPT5woZ4QdjGnTjfqqzNbtyeG2xBgZM732OXXek). There are several libraries in Ubuntu implementing cryptographic algorithms (ciphers, hashes, …) and protocols (TLS, SSH, …). Hundreds of packages offer crypto-related configurations and these usually take precedence over system-wide library configuration. At least Java, Golang and Rust have their own crypto libraries. This amounts to hundreds if not thousands of configurations to perform. Moreover, several aspects are tricky to get right and version changes can cause breakage. ## **Lack of consistent configuration: case study on Mantic Minotaur** | Software | Nginx | Apache | Mariadb | Postgres | Mysql | Exim | Rabbitmq | | :---- | ----- | ----- | ----- | ----- | ----- | ----- | ----- | | Ciphers | Baseline | Baseline | ~~CAMELLIA ARIA CCM~~ | Baseline | ~~CHACHA20 POLY1305~~ | ~~CCM ARIA CAMELLIA AES-SHA\>128~~ | ~~ARIA CAMELLIA~~ ECDH | | Key Exchange | Baseline | Baseline | Baseline | P-256 only | P-256 ~~x25519 x448 ffdhe\*~~ | TLS1.3: CCM P-384 P-512 x25519 x448 | TLS1.3: CCM P-256 brainpool sect\* secp\* | | Bonus | | Actually: TLS1.2: ~~AES128~~ | | | | TLS 1.0 TLS 1.1 | TLS 1.0 TLS 1.1 Erlang OTP | At the moment (Mantic Minotaur), there are countless differences between the default cryptographic configuration of packages in the archive, especially for TLS. The results below have been obtained by enabling TLS support and configuring a certificate in nginx, apache, mariadb, postgresql, mysql, exim and rabbitmq. No further step was carried on in order to find what is the closest to a default configuration. It is likely that users run with these configurations, as can be seen through censys.io (internet-wide host scan database) which shows a large number of ubuntu machines running exim with TLS 1.0 and 1.1 enabled. Compared to nginx' configuration: - **apache** disables AES128 for TLS 1.2 (but not TLS 1.3 \[ where it's specified as mandatory \]) - **mariadb** disables CAMELLIA, ARIA, and CCM mode for AES - **postgres** only exposes P-256 for key exchange, no matter the TLS version - **mysql** disables CHACHA20-POLY1305 for TLS 1.2 (but not TLS 1.3 \[ where it's specified as mandatory \]), it also disables key exchanges that are not P-{256,384,512} (i.e. x25519, x448, ffdhe\*) - **exim** disables CAMELLIA, ARIA, CCM8 mode for AES (but not CCM mode which it even enables when doing TLS 1.3), AES256-SHA384 and AES128-SHA256 but not AES{128,256}-SHA; it enables more curves for key exchanges; it also still enables TLS 1.0 and 1.1 - **rabbitmq** disables ARIA and CAMELLIA and enables ECDH (which uses a lot of CPU), it enables CCM and CCM8 modes with TLS 1.3; with ECDH it enables CBC mode for AES ; it doesn't offer P-521 for key exchange with TLS 1.3 ; it enables many many curves for key exchange with TLS 1.2, including some as small as 163 bits (equivalent security: 81 bits for symmetric encryption) which is widely considered inadequate for more than 10 years ; finally it also enables TLS 1.0 and 1.1. The topic here is not about which configuration is better but how users can be anything but lost with so many widely different configurations. ## **Moving security forward** | 💡Using the same cryptography configuration for all software on Ubuntu and for all Ubuntu users actually means sticking to legacy and lenient configurations. We need configuration values that are consistent per-ecosystem rather than across the distribution in order to not tie ourselves to the slowest moving ecosystems (i.e. e-mail). | | :---- | How to make our default configurations be on the forefront rather than trailing? Standards or good practices typically mandate sets of algorithms but not all algorithms from these sets are the same. These sets typically include some algorithms meant for the future, some for current usage and some for compatibility with legacy systems in order to maintain compatibility over time and be able to gradually update systems. Completely forbidding deprecated algorithms in crypto providers is possible (although this will sometimes involve writing code). Is it enough? As explained above, at any given time, we are likely to enable some algorithms for compatibility with legacy. Should they be enabled system-wide by default though? And if they're disabled by default, should enabling them always be system-wide? I argue that we should aim to disable legacy algorithms and protocols by default and enable them per-application based on every application's environment. TLS 1.3 is understood by 97% of the used web browsers while TLS 1.2 (our current minimum) is understood by 98% of them. The difference is old and non-updated browsers; should we be held behind because of them? On the other hand, mail servers probably still require TLS 1.2 in many cases. As such, we might want something like the following: ![][image1] ``` Relative security ^ | +-----------------+| +---+ +---+ +---+ | Modern {g} || | | | N | | p | +-----------------+| | | | g | | s | | | E | | i | | q | +-----------------+| | x | | n | | l | | Current {g} || | i | | x | | | +-----------------+| | m | +---+ +---+ ┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄+┄+┄┄┄+┄┄┄┄┄┄┄┄┄┄┄┄┄┄ +-----------------+| | | | Legacy {o} || | | +-----------------+| +---+ ┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄+┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄┄ +-----------------+| Systemwide minimum | Deprecated {r} || +-----------------+| # Legend: g = { fill: #93c47d; } o = { fill: #f5b26b; } r = { fill: #e06666; } ``` ## **Crypto-config overview** | 💡Crypto-config works by introducing an indirection in the path of configuration files. This is as if '/etc' were actually a symlink that you could point to either '/etc-lenient' or '/etc-hardened', except that it only applies to some files that the package maintainer opts into the scheme. The base implementation is 'ln \-sfn'\! There is some architectural work to make everything smooth for both Ubuntu developers and users but it is fairly well-bound and this document should cover everything. The majority of the work is providing meaningful and wise configuration choices to users so that they don't have to face the complexity of configuring everything themselves. In other words, that's typical distribution work. | | :---- | Applications have their own configuration but they also use libraries which can also have their own configuration. For instance, Nginx reads "default.conf" but it also uses openssl which can read "openssl.cnf". This typical setup is shown below for several applications. In these pictures, each cell in the left column corresponds to the cells on the same line on the right side. ![][image2] ``` .-----------------------. | .-----------------------. .-----------------------. .---------. .-----------------------. .---------. .---------. | Cryptography User | | | Apache2 | | Nginx | | ... | | Exim4 | | ... | | ... | '-----------------------' | '-----------+-----------' '-----------+-----------' '---------' '-----------+-----------' '---------' '---------' | +-------------. +-------------. +-------------. | | | | | | | | v | v | v | .-----------------------. | .-----------------------. | .-----------------------. | .---------. .-----------------------. | .---------. .---------. | Configuration | | | ssl.conf | | | default.conf | | | ... | |"03_exim4...tlsoptions"| | | ... | | ... | '-----------------------' | '-----------------------' | '-----------------------' | '---------' '-----------------------' | '---------' '---------' | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | v v v .-----------------------. | .-----------------------------------------------------------------. .-------------------------------------. .---------. | Cryptography Provider | | | OpenSSL | | GnuTLS | | ... | '-----------------------' | '-------------------------------+---------------------------------' '------------------+------------------' '---------' | | | | | | | | | | v v .-----------------------. | .-----------------------------------------------------------------. .-------------------------------------. .---------. | Configuration | | | openssl.cnf | | "gnutls/config" | | ... | '-----------------------' | '-----------------------------------------------------------------' '-------------------------------------' '---------' | | | | | ``` With crypto-config, the first idea is to have the following instead: every configuration file can refer to data through the crypto-config framework, therefore making it possible to have a single source of truth for the cryptography configuration. ![][image3] ``` .-----------------------. | .-----------------------. .-----------------------. .---------. .-----------------------. .---------. .---------. | Cryptography User | | | Apache2 | | Nginx | | ... | | Exim4 | | ... | | ... | '-----------------------' | '-----------+-----------' '-----------+-----------' '---------' '-----------+-----------' '---------' '---------' | +-------------. +-------------. +-------------. | | | | | | | | v | v | v | .-----------------------. | .-----------------------. | .-----------------------. | .---------. .-----------------------. | .---------. .---------. | | | | ssl.conf | | | default.conf | | | ... | |"03_exim4...tlsoptions"| | | ... | | ... | | | | '-----------+-----------' | '-----------+-----------' | '---------' '-----------+-----------' | '---------' '---------' | Configuration | | | | | | | | | | | v | v | v | | | | .-----------------------------------------------------------------------------------------------------------------------------. | | | | "crypto-config" | '-----------------------' | '-----------------------------------------------------------------------------------------------------------------------------' | | | | | | | | | | | | | v v v .-----------------------. | .-----------------------------------------------------------------. .-------------------------------------. .---------. | Cryptography Provider | | | OpenSSL | | GnuTLS | | ... | '-----------------------' | '-------------------------------+---------------------------------' '------------------+------------------' '---------' | | | | | | | | | | v v .-----------------------. | .-----------------------------------------------------------------. .-------------------------------------. .---------. | | | | openssl.cnf | | "gnutls/config" | | ... | | | | '-------------------------------+---------------------------------' '------------------+------------------' '---------' | Configuration | | | | | | | v v | | | .-----------------------------------------------------------------------------------------------------------------------------. | | | | "crypto-config" | '-----------------------' | '-----------------------------------------------------------------------------------------------------------------------------' ``` While this is enough to cover the majority of applications, there is still an issue with hard-coded values in applications and applications initializing libraries in a way that doesn't parse the library configuration. We would also like to be able to apply changes system-wide by only touching the cryptography provider. Due to limitations in cryptographic libraries, these will require patches. Such patches exist in Fedora/RHEL but while the ones for e.g. openssl achieve the desired outcome, they probably cannot be upstreamed without large changes. Consider the source of configuration values in an application like nginx: 1) defaults in the openssl binaries 2) openssl configuration 3) defaults in the nginx binaries 4) nginx configuration Today nginx configures the list of enabled ciphers using either a default value built into nginx, or a value which comes from its configuration. There is however no value which means "use what is defined system-wide". A system administrator would have to manually transcribe the system-wide configuration into nginx' configuration. While this is somewhat possible for a single application, it doesn't scale at all. Addressing this situation is the second category of changes for crypto-config. Both approaches are complementary. Acting at the level of crypto providers ensures no application runs with a forbidden algorithm. Configuring applications directly makes it possible to move some of them forward faster than others: indeed, cryptography for the web has improved much faster than for e-mails which is hindered by backward-compatibility for its federative model. It is important to keep in mind that in every case, sifting through the Ubuntu archive will be needed in order to ensure packages properly follow this specification. This isn't actually additional work since such [an audit is already needed as shown previously](#lack-of-consistent-configuration:-case-study-on-mantic-minotaur). ## **Applicability to non-crypto domains** Little of what is described below is limited to cryptography. The only reasons to limit this to cryptography are not technical but practical. Indeed, the goal is to cover a whole domain with a single configuration value and there doesn’t seem to be another field for which this would make sense or be doable. In the event such a field is found, the process below would result in a second configuration value that is independent from this one anyway. Indeed, the whole point of this approach is to have users not need to consider combinations of options. # **State of the art: Fedora’s crypto-policies** | 💡Here we quickly come back to why adopting crypto-policies from Fedora/RHEL is not useful nor desirable. | | :---- | We have analyzed Fedora’s crypto-policies as part of [US021](https://docs.google.com/document/d/1dqgp44bU6gSiyc-nNBB5gbPFElQJZ-yb3Caj-IJ113M). It is too RH-specific to use as-is and not interesting enough to reuse and improve upon. On the plus side, it seems that it properly lets admins of RH systems experience the upcoming change in defaults in RH by running a simple command. People seem satisfied with a small featureset. However: * the implementation is too complicated since it tries to generate configuration for everything from a single configuration file, * there has been only one important (public) use case for it so far (deprecating SHA-1), * its UI is lacking (there is almost no UI at all actually), * it might be impossible to have the host rules apply to snaps. My criticism of crypto-policies can be summarized as attempting to solve an uncommon use case in a fully generic way and ending up being so complex that the genericity becomes a hindrance for both developers and users. Moreover, I’d wager that most of the development time is spent on fixing it, leaving no time to make it nice to use. Moreover, writing policies seems time-intensive. Crypto-policies is however very interesting since it is the only software and process that exists in this space today. It therefore constitutes a comparison point. The project also includes a policy for packaging that we can get inspiration from. # **Rationale for a new policy and tools** Fedora has been shipping a ‘crypto-policies’ tool for several years. While its goals appealed to us, we have deemed it not appropriate for Ubuntu. This leaves us with a few choices: a) not provide anything, b) find something else that already exists, c) write something ourselves. Customers have not yet expressed a strong urge to have such a tool but this is a growing demand and some customers (IBM-cloud) are asking for this. There is also an internal demand for it. There seem to be no existing tools we could use or at least evaluate. This is not very surprising since one of the reasons we rejected Fedora’s crypto-policies is its complex ties to Fedora as it depends on the rest of the configurations in the distribution, on the software versions and even distribution patches (for instance, there is a special case related to RSA key length for openssh). While it has been packaged and uploaded to Debian, crypto-policies has never been linked to the reset of the system and it has finally been removed in July 2024\. It should be noted that since diverging from Debian is costly, we would prefer something that Debian also adopts or that at least implies a minimal diff. Adoption of policies and tools by Debian does not imply that Ubuntu and Debian will use the same configuration. This leaves us with writing a tool ourselves. I believe there is a simple path forward that will let us have clearer configuration files that can be easily tweaked by users. I also believe there is a lot of value in bringing this to customers. This is done in baby steps that are also very natural: the risk with each step is minimal and the project can be paused at any time with no need to rollback anything. # **User stories** As a sysadmin, I would like to select a configuration policy that applies to all supported services system-wide both for defaults settings and minimum ones. As a sysadmin, I would like to know which software lowers the crypto settings of its crypto providers. As a sysadmin, I would like to disable a given algorithm system-wide at a given date (e.g. SHA1 at the end of 2030). As a sysadmin, I would like to disable a given algorithm system-wide but re-enable it selectively (e.g. a specific machine cannot be upgraded and only supports legacy cryptography). As a sysadmin or developer, I would like to test a Ubuntu system with some algorithms or protocols disabled in order to assess compatibility (e.g. with upcoming deprecations). As a developer of software that will run on Ubuntu, I would like to provide users with typical configuration values for them to choose from, reducing documentation burden and support requests. As an Ubuntu developer, I would like to more easily know which crypto algorithms and configurations are configured and in use. As a developer of software, I’d like to know which of the myriad of crypto options are recommended and reliable. This ranges from security considerations like “is it secure” to compatibility ones “is it working across all supported Ubuntu releases”. As an Ubuntu developer, I would like to simplify the task of providing compliant configuration settings by using an integrated system which allows specifying the relevant settings for the various compliance frameworks. ## **Other constraints, motivations and design goals** In addition to user wishes and needs, there are additional constraints to take into account. ### **Guarantee consistency and don't break systems** ### Centralizing configuration risks breaking every related package at once: upgrading the central crypto-config package can break packages which rely on it. The central package should therefore be simple and developed with care in order to minimize this risk. ### **Handle package upgrades, removals and purges** Care must be taken not to provide fewer guarantees than the usual configuration handling in Debian. ### **Limit dynamism in configuration** Dynamism can be useful but we want a safe and deterministic system. It should behave similarly as configuration handling in Debian packages and provide at least the same guarantees, especially those of safety. ### **Don't require lockstep upgrades / transitions** We don't want to lock everything together. Requiring a transition for every crypto provider and user would be terrible. This implies some dynamism in profiles. Indeed, consider package A which knows profiles X and Y; when adding profile Z, if there is no mechanism to automatically populate A's configuration files for Z, package A must be updated. This would apply to every enrolled package, effectively starting a very large transition. In other words, packages built at a given moment should be forward-compatible with profiles introduced later on. In order to achieve this kind of compatibility, there must be dynamism after package creation, i.e. when installing. This will involve dpkg triggers as explained in the specification. ### **Avoid incompatibilities with Debian** As a Debian downstream, deltas are costly and incompatibilities require constant work. Moreover we would like Debian to be able to use this work. Provisions should be taken to ensure differences with Debian, whether it is not using this work or it is, do not cause undue burden on Ubuntu developers. # **Specification** NB: examples in this section use ‘nginx’ because its configuration format is simple; the same can be done with openssl. ## **Constants used in the specification** ``` DATA_DIR=/usr/share/crypto-config SYSTEM_PROFILES_DIR=${DATA_DIR}/profiles STATE_DIR=/var/lib/crypto-config STATE_PROFILES_DIR=${STATE_DIR}/profiles SYSCONF_DIR=/etc/crypto-config SYSCONF_PROFILES_DIR=${SYSCONF_DIR}/profiles ``` ## **In a nutshell** ``` SYSTEM_PROFILES="${SYSTEM_PROFILES_DIR}" CURRENT_PROFILE="${STATE_DIR}/current" ### new files: regular file: ${SYSTEM_PROFILES}/post-quantum/nginx/ssl-ciphers.conf regular file: ${SYSTEM_PROFILES}/default/nginx/ssl-ciphers.conf symlink: ${CURRENT_PROFILE} to post-quantum/ or default/ ### modified with “include ${CURRENT_PROFILE}/nginx/ssl-ciphers.conf": /etc/nginx/nginx.conf ### Run crypto-config switch post-quantum ``` ## **Overview** | 💡Packages install variants of their cryptography configuration and a post-installation dpkg trigger merges them across applications into profiles. Users can use a tool to change the system from one profile to another. There will also be work to ensure all software actually follows the system configuration (proof that all software doesn't work together out of the box: we're still not out of job). | | :---- | * All crypto providers are enrolled in the current scheme; this will indirectly enroll their users too * Crypto users can also optionally be enrolled in order to tune their behavior more finely * Only deal with the organization of configuration files and add tooling to switch between sets of configuration snippets that already exist. * Packages’ crypto configurations are extracted into dedicated configuration files. * Ubuntu ships sets of Canonical-written configuration files for each supported system-wide configuration * The same packages that ship configurations continue to do so and adapt to the new organization * Packages install their sets of configuration files under ${SYSTEM\_PROFILES\_DIR}/\/\/ * A tool is then triggered to fill potential gaps in the profiles through inheritance and installs the result in ${STATE\_DIR}; the tool can also be called from postinst scripts when needed (postinsts run before triggers do). This tool is described in the [Profile inheritance](#profile-inheritance) section. * We decide which profiles we want to provide and make mandatory to support by crypto providers; this includes at least one named “default” * Every software enrolled in this scheme ships sets of configuration snippets for the default profile and optionally provide snippets for other profiles * The configuration snippets are referred to by configuration files through the ${STATE\_DIR}/current path * Configuration snippets are static * Users can write configuration snippets and create configuration sets but do so without being provided specific support at the moment * The configuration choices should be forwarded to snaps (but this is out of scope for the current specification) * We create a tool for system administrators to manage the link to the current profile * We want to minimize differences from both upstreams and Debian ## **Policy** | 💡This is mostly the set of rules required for packages to \_actually\_ use system-wide configurations. For instance, if there is a default set of TLS ciphers configured in openssl, applications can change that to almost anything and they very often do. We will therefore work towards making applications use a system-wide value by default (users can still configure them differently). The number of rules is due to how different every software in Ubuntu is. | | :---- | * This policy restricts what packages can do in order to make configuring software more manageable by the human users. In essence it defines an interface between users and software crypto configuration files. * It seems impossible to be less restrictive than this proposal while actually improving the situation since users are looking for complete or near-complete coverage * Packages already in main when the policy comes into effect automatically enter this scheme with a legacy status and will be evaluated over time for actual compliance. As such this policy doesn't put additional constraints on existing packages the day it comes into effect. * This policy becomes a requirement for new packages in Ubuntu main starting with the development of 25.04. * Crypto providers are libraries such as openssl * Crypto users are software that uses these providers; this includes both applications and libraries * Crypto users can also be crypto providers (e.g. openssh which implements cryptography but also uses openssl). * Crypto users that use hard-coded values to configure their crypto provider must now also accept overrides from their configuration * Crypto users must not use API calls to change crypto providers' configuration values that are configured under this scheme at the level of the crypto providers themselves * Crypto providers accept configuration through the current framework * Canonical-supported snaps should also abide by this policy; details are to be laid out in a dedicated specification * There is no hard rule to decide whether a configuration value must be handled through this framework. * Configuration values that are handled through this framework are extracted into dedicated files and used through “include” or similar configuration directives. ### **Exceptions** * Exceptions to the policy can be granted by the Ubuntu Technical Board (this may especially make sense for systems dealing with data at rest, and databases in particular) ### **Reporting and introspection** | 💡Some APIs of crypto providers can have a large impact on the effective configuration of the system (e.g. by changing the path of the system configuration to /dev/null, or by changing global options). These APIs also have legitimate usages which makes it impossible to outright forbid them. Moreover, static analysis is limited and does not cover software outside of Ubuntu. It will therefore be useful to dynamically query applications to learn if they have used such APIs. | | :---- | * Crypto providers expose a symbol or USDT probe which reports whether a crypto user has used configuration APIs which do not match the policy above. ## **Paths** | 💡Packages install configuration snippets in /usr. Running software uses configuration data from under /var/lib. A dpkg trigger reads from /usr and populates /var/lib, handling profile inheritance. | | :---- | * Files provided by the distribution are installed inside ${SYSTEM\_PROFILES\_DIR} * Users use ${SYSCONF\_PROFILES\_DIR} to create profiles; in case of a name conflict, distribution profiles take precedence * Packages configurations only refer to ${STATE\_DIR}/current which is a symlink that always points to the current profile * Files in ${SYSTEM\_PROFILES\_DIR} and ${SYSCONF\_PROFILES\_DIR} are internal data for the crypto-config tools which uses them to create full profiles in ${STATE\_PROFILES\_DIR} which match the file structure expected by packages * Every profile is a collection of dropins for packages; how these dropins are internally organized is up to each package's maintainer * Crypto-config handles the collection of dropins for every package as black boxes * Besides "default", profiles have no obligation to ship dropins for a given package; these will be filled in according to the rules laid out in [Profiles design](#profiles-design) and [Profile inheritance](#profile-inheritance) * After a package operation changes files under ${SYSTEM\_PROFILES\_DIR}, a tool copies profiles from both ${SYSTEM\_PROFILES\_DIR} and ${SYSCONF\_PROFILES\_DIR} to ${STATE\_PROFILES\_DIR}; there the profiles are filled in according to the aforementioned rules * All profiles are merged in ${STATE\_DIR} and used from there * There is no support for merging profiles across these directories. * There is no support for drop-ins (they don't make sense here). * There is no dedicated support for masking profiles (e.g. through the creation of symlinks to /dev/null in directories with a higher precedence) since any profile created in a directory with higher precedence masks those of the same names in directories of lower precedence * If needed, configuration for the tool itself will go in ${DATA\_DIR}/crypto-config.conf.d or ${SYSCONF\_DIR}/crypto-config.conf.d * All profile names are reserved for distribution use except those starting with 'local/' or 'site/' (this is achieved by storing profiles in subdirectories); this may be relaxed in the future once crypto-config has been used more. ### **Without crypto-config** ![][image4] ``` .----------------------. .----------------------. | | | | | .deb package | | User | | | | | '-----------+----------' '-----------+----------' | | | | |dpkg installs |Edits | | v | .----------------------. | | | | | Application | | | | | '-----------+----------' | | | | | |Reads | | | v | .----------------------. | | | | | Config | | | | | | |<---------------------------------------' | | '----------------------' ``` ### **With crypto-config** ![][image5] ``` .----------------------. .----------------------. | | | | | .deb package | | User | | | | | '-----------+----------' '-----------+----------' | | |dpkg installs | +------------------------. |Creates | | | v v v .----------------------. .----------------------. .----------------------. | | | Files | | Files | | Application | | in | | in | | | | "SYSTEM_PROFILES_DIR"| |"SYSCONF_PROFILES_DIR"| '-----------+----------' '-----------+----------' '-----------+----------' | | | | | "crypto-config" | |Reads | generates | | `-----------. .----------' v | | .----------------------. | | | | v v | Config | .----------------------. | .----------------. | Uses | Profiles | | |"crypto-config" +--+--------------->| in | | '----------------' | | "STATE_PROFILES_DIR" | '----------------------' '----------------------' ``` ### **Profiles and dropins collections** ![][image6] ``` +--------------------+ +--------------------+ +--------------------+ | .----------------. | | .----------------. | | .----------------. | | |GnuTLS dropins | | | |GnuTLS dropins | | | |GnuTLS dropins | | | '----------------' | | '----------------' | | '----------------' | | .----------------. | | .----------------. | | .----------------. | | | Nginx dropins | | | | Nginx dropins | | | | Nginx dropins | | | '----------------' | | '----------------' | | '----------------' | | .----------------. | | .----------------. | | .----------------. | | |OpenSSL dropins | | | |OpenSSL dropins | | | |OpenSSL dropins | | | '----------------' | | '----------------' | | '----------------' | | .----------------. | | .----------------. | | .----------------. | | | ... | | | | ... | | | | ... | | | '----------------' | | '----------------' | | '----------------' | +--------------------+ +--------------------+ +--------------------+ "'Default' Profile" "'Legacy' Profile" "'Future' Profile" ``` ## **Profiles design** | 💡Designing profiles is a task that requires dedicated work: the data needs to be stored in a way that can be made sense of afterwards. This is initially constraining but mostly one-time work to enable profile inheritance (which is described in a subsequent section), and proper UI/UX for users. | | :---- | * Ubuntu ships a number of profiles through the crypto-config package * Profiles contain a file metadata.json with the following values: * pretty-name * summary (a few words, at most a line) * description * maintainer (mostly future-proofing for user customization) * parent (for inheritance across profiles) * condition (a shell command which must succeed for the profile to be visible and usable) * DIrectories without metadata are ignored * Profile design, layout and metadata is decided and authored at the distribution-level * For any profile except the default one, a package either ships no file and no directory, or ships the same list of files as the default profile * The list of collections of package dropins in the default profile is the single source of truth for enrolled packages on the system * All profiles must inherit directly or indirectly from the default profile. Without inheritance, creating a new profile would require adding support for it in every enrolled package; with it, the dropins collections from the parent are used until more specific one are added to the application package (if wanted) * Inheritance happens at the level of dropins collections, not dropins themselves since their set is dynamic and their inheritance would therefore be complex * Profiles form a tree through their inheritance relationships * Consistency between profiles for an application is mostly achieved by the fact that they are maintained as part of the same package ## **Profile inheritance** | 💡Profile inheritance creates a profile that uses the same configuration data as another one except for some software. The inheritance is coarse: it occurs at the application-level, not at the level of configuration snippets which would be a much more complicated task, maybe even an undecidable one since that would require parsing every configuration format and making sense of it. If a maintainer (or user) wants to reuse some snippets, it should be done in a traditional way, possibly with symlinks to well-known files. The inheritance is implemented through a program called every time configuration snippets are touched through a dpkg trigger. The process is deterministic and idempotent and can be used for user-customization (this will work but is not officially supported at this time). | | :---- | The inheritance process paves the way for user-customized profiles but there are additional aspects to take into account, mostly around conffile handling before officially supporting user-customization. * Nothing here changes any file directly managed by dpkg; every operation described below happens inside ${STATE\_DIR}. * Whenever a package installs or removes collections of dropins, a tool is automatically started at the end of the packages' configuration or de-configuration and guarantees the presence, validity and coverage of every profile in ${STATE\_DIR} based on the installed collections of dropins. * When a package does not provide a directory of snippets for a profile, a symlink to the one in the parent profile is created in its place. * Existing regular files are not modified. * Existing symlinks are replaced by symlinks to the parent's dropins collection. * This resolution is done starting from the top of the inheritance tree (the default profile) and towards its leaves, therefore guaranteeing everything resolves eventually * Example: consider profiles and inheritances "default" \-\> "x" \-\> "y" \-\> "z" * Profile "default" covers application "foo" * Profile "x" does not; "foo" will be created as a symlink to the directory from profile "default" * Profile "y" covers it, nothing else will be done * Profile "z" does not; "foo" will be created as a symlink to the directory from profile "y". * We can prove the inheritance resolution process always succeeds: * a profile either contains dropins collections for every enrolled packages, or lacks some * by construction the default profile lacks no dropins collection * a profile that lacks some dropins collection and which parent lacks none has all its missing dropins collections filled in as symlinks to the parent profile and therefore does not lack dropins collections anymore * therefore all profiles that inherit from the default profile lack no dropins collections and the process can be applied recursively to their children * by induction, after the whole process, all profiles that inherit directly or indirectly from the default profile lack no dropins collections. ### **Example profile inheritance tree** ### **![][image7]** ``` +------------+ | Default | +--+-+--+-+--+ | | | | .------------------' | | '------------------. | .----' '----. | | | | | v v v v +-----------+ +-----------+ +-----------+ +-----------+ | Legacy | | FIPS | | Future | | Customer- | | | | | | | | specific1 | +-----------+ +-----+-----+ +-----------+ +-----------+ | v +-----------+ | Customer- | | specific2 | +-----------+ ``` ### **Example dropins collection re-uses across profiles** ![][image8] ``` +-----------------------------------------------------------+ | | | +------------+ +-----------+ +------------+ | | Default | GnuTLS {g} | | Nginx {g} | | OpenSSL {g}| | ,->| +------------+ +-----------+ +------------+ | | | ^ ^ ^ | | +-------------------|---------------|--------------|--------+ |Inherits from | Reuses | | Reuses | +-------------------|---------------|--------------|--------+ | | | | | | `--| +------------+ +-----------+ +------------+ | | Legacy | GnuTLS {b} | | Nginx {g} | | OpenSSL {b}| | ,->| +------------+ +-----------+ +------------+ | | | ^ ^ ^ | | +-------------------|---------------|--------------|--------+ |Inherits from | Reuses | Reuses | | +-------------------|---------------|--------------|--------+ | | | | | | `--| +------------+ +-----------+ +------------+ | | "Customer2" | GnuTLS {b} | | Nginx {b} | | OpenSSL {g}| | | "-specific" +------------+ +-----------+ +------------+ | | | +-----------------------------------------------------------+ Legend: +------------+ | {b} | Dropins are symlinks to dropins in another profile +------------+ +------------+ | {g} | Dropins are regular files in the current profile +------------+ # Legend: g = { fill: #93c47d; } o = { fill: #f5b26b; } r = { fill: #e06666; } b = { fill: #cfe2f3; } ``` ## **Packages** | 💡Here we go through how crypto-config will be shipped and installed, and its impact on existing packages. | | :---- | ### **crypto-config** * New package * Installs the metadata of the profiles that are included in Ubuntu * Provides a shell script for supporting the installation and configuration of enrolled packages for use by dpkg * Provides a tool for managing the configuration (which specification is in the [Tool](#user-facing-tool) section) * Registers a dpkg trigger on ${SYSTEM\_PROFILES\_DIR} in order to run the inheritance resolution every time the policies are modified ### **Directly enrolled packages** * Directly enrolled packages include: * all identified crypto providers (with the goal of identifying all of them) * voluntary crypto users, i.e. ones for which finer control over the crypto configuration is wanted * All packages directly enrolled in this scheme depend on the central crypto-config package * These packages must ship a configuration that splits apart its crypto aspects either directly or through drop-ins * These packages install at least a dropins collection for the default profile ### **Other packages** * Other packages are unchanged ## **User-facing tool** * This specification deals with basic tooling only; other tools can be specified elsewhere or developed without specification, by Canonical or by others * The tool can show the user the profile currently in use * The tool can show the user the list of available profiles * The tool can atomically and safely switch the system between policiesrestart * After a profile switch, the tool advises the administrator to reboot the system if necessary. * Packages should at least Recommends: this tool. Depending on the package and dependencies size, we might prefer Depends: . * The tool shall be written in shell script or Rust since it will be installed on most installations of Ubuntu, even minimal and maybe recovery systems * The tool implements at least the command-line interface below: ``` help, -h, --help display command-line help status show the currently-used profile switch PROFILE switch to PROFILE query profile-condition PROFILE value of `condition` in PROFILE's metadata query profile-current profile currently in use query profile-description PROFILE value of `description` in PROFILE's metadata query profile-list-all list all profiles, including disabled ones query profile-list list profiles query profile-maintainer PROFILE value of `maintainer` in PROFILE's metadata query profile-parent PROFILE value of `parent` in PROFILE's metadata query profile-path PROFILE value of `path` in PROFILE's metadata query profile-summary PROFILE value of `summary` in PROFILE's metadata query application-path PROFILE PACKAGE location of the profile for PACKAGE in PROFILE with symlinks not resolved query application-realpath PROFILE PACKAGE location of the profile for PACKAGE in PROFILE with symlinks resolved query application-realprofile PROFILE PACKAGE profile that holds the application-realpath for PROFILE and PACKAGE ``` ## **Configuration sealing** | 💡Writing consistent data in configuration files is wonderful but mostly useless if end-applications don't actually use it\! Applications too often don't follow whatever configuration exists for their crypto provider and have their own instead. | | :---- | * Every crypto user must initialize its crypto providers' crypto settings to either their system defaults or to a value that is set in one of the crypto user's configuration files * NB: some applications (namely OpenConnect) disable system configuration on purpose and will need patches unless a proper solution is devised with upstream * When a configuration change that would lower the security of crypto settings (as in the sense expressed in [Annex: bits of security, comparable algorithm strengths, and boiling oceans](#annex:-bits-of-security,-comparable-algorithm-strengths,-and-boiling-oceans)), crypto providers must make it possible through their configuration, to ignore the requested changes, and either: a) return an error if the already-existing API and code make it possible, b) return success, or c) abort the application. * Crypto providers must log calls to APIs that achieve any of the aforementioned. * Apparmor profiles must allow access to the relevant configuration files. * NB: starting with Noble Numbat and as a consequence of the work on this topic, the default apparmor configuration allows access to openssl and gnutls; this will be expanded to include relevant directories as this work moves forward. ## **Statically-linked crypto providers** | 💡This section is spurred by Go and Rust which use static-linking and have their own implementations of crypto providers. The issue is more general however: every statically-linked crypto provider raises the same issue. | | :---- | Static linking is used to de-correlate an application from the system's shared libraries. In Ubuntu, configuration is linked to the system's shared libraries. It follows that static linking de-correlates applications from the system's configuration. Indeed, an application could ship any version of any crypto provider from the past or from the future relative to a Ubuntu version, and the configuration format, values and consequences could be vastly different. The issue would be somewhat better if configuration files were versioned but this is rarely the case. * Statically-linked crypto providers are out of scope. # **Affected packages** ## **Crypto providers** Crypto providers include at least the following: * GnuTLS * Kerberos * libssh * NSS * OpenJDK * OpenSSH * OpenSSL * StrongSwan * cryptopp * gnupg * libgcrypt * libnacl * libsodium * libtomcrypt * mbedtls * nettle * paramiko * postgresql * sequoia * wireguard * wolfssl There are also providers that are probably not directly affected by this: * linux * openzfs We should also keep in mind packages that expose some hardware's acceleration features. ## **Crypto users** There is no fixed list of crypto users to enroll into this scheme, only guidelines. The following can be taken into account in order to decide if a package (be it in main or in universe) should be effectively enrolled and with which priority. * Depends on a crypto provider through a dynamic library, an executable or an RPC * Would behave differently across profiles if enrolled * Would bring value to users by being enrolled There is no guaranteed criteria indeed: if 'md5sum' were relying on gnutls or openssl, it would be a crypto user but enrolling it wouldn't bring any value to users since its behavior would have to remain forever identical, including across profiles. The most effective criteria is the Depends and Recommends of a package as with the following command-line filter: grep-dctrl \-e 'libssl3|libnss3|libgnutls30|libssh-4|libkrb' \-FDepends \-FRecommends \\ | grep-dctrl \-v \-e 'universe' \-FSection \-sPackage and with this command: (for i in nss gnutls28 openssl; do reverse-depends \-b src:$i \-c main \-l ; done) | sort | uniq These two approaches yield respectively 256 packages in main and 1305 with universe, and 162 packages in main and 1027 with universe. These two approaches are not directly comparable and both should be used. It is important to acknowledge that there will be gaps simply due to the number of packages involved and this is why it is important to take the value for users into account. # **Example: usefulness with krb5** Until version krb5 1.20-1, the kdc.conf file shipped with Ubuntu included the following: master\_key\_type \= des3-hmac-sha1 As far as I understand, this was fixed because the krb5\_newrealm outputs a deprecation warning. We would have appreciated that this was found earlier on. Had this configuration been split into a dedicated file and organized into profiles, it would have been trivial to find it in an automated fashion. Indeed, it would be very easy to automatically extract all files that make up profiles across the archive and analyze them either automatically, or by hand. Obviously the work leading to splitting this from configuration files would also have been able to surface this issue but this depends on when the splitting is done and what is considered secure at that time. # **Known Limitations and Future work** ## **Known Limitations** ### **Missing configuration snippets for a software package when using a user-defined profile** One can imagine situations where the default profile starts using a new configuration snippet, other profiles are not updated to use it. This is only a small issue for profiles provided by the distribution. It is not actually a new problem: it merely adds new files and paths to manage when updating packages. This is more an issue for user-designed profiles since they are not updated at the same time. At the moment, user-designed profiles are not supported so we have time to identify issues like this one and address them. In the future, we can imagine tooling that will identify such issues ahead of time by comparing the set of files in each snippet in order to warn of missing files. ## **Future work** ### **Creating dh\_crypto\_config and lintian checks** At the moment, the installation of profiles in packages is manual. They will typically be added under debian/conf/ and listed in debian/foo.install. One could imagine a dh\_crypto\_config that would install profiles detected under debian/crypto-config . Similarly, lintian could be used to ensure the profiles in a package are consistent. It is probably too early to add a lot of automation and it is probably better to first get more real-world experience. Also, debhelper and lintian are written in perl. ### **Autopkgtest** Profiles change the behavior not only of the package but also of the system. It will be useful to run autopkgtests under various profiles. Maybe the only requirement will be to run tests in a loop, changing profile and restarting services each time. In any case, actual experience developing packages and profiles will probably be useful first. Autopkgtests will also be most useful as a way to track upstream changes. Conversely, they will also be most needed when there are more than a few packages effectively enrolled. # **Further Information** ## **Annex: bits of security, comparable algorithm strengths, and boiling oceans** The choice of cryptographic algorithms and sizes has long been difficult and there is often no obvious answer when it comes to comparing them. They are also very abstract. Indeed, what does it mean to use AES128? It's the standard symmetric cipher nowadays and no-one is going to be fired for choosing it but why not use AES256 then, and could something else be appropriate too for some given usage scenario and threat model? A notion that has taken hold is the bits of security: some algorithm is said to provide N bits of security at a given time with the current scientific knowledge (breakthroughs are rare but can change everything). Bits of security is still an abstract notion but can be applied to most algorithms, if not all. This leads to results such as SHA1 provides X bits of security, SHA256 provides Y bits of security and BLAKE2b-512 provides Z bits of security. This doesn't apply across different kinds of cryptographic algorithms but this is not an issue in practice since different usage scenarios require different kinds of such algorithms anyway. [NIST \- Recommendation for Key Management](https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-57pt1r5.pdf) : 5.6 Guidance for Cryptographic Algorithm and Key-Size Selection It is worth mentioning [Universal security from bits and mips to pools, lakes – and beyond](https://eprint.iacr.org/2013/635.pdf) by Lenstra et al in 2013\. The authors build humorous comparisons between cracking cryptographic algorithms at various bit-lengths and the volume of water that would be boiled with the same amount of energy. ## **Annex: Possible work split** Below is a rough outline for one of the possible development plans. There are two or three major batches. Tasks will sometimes be done in parallel. ### **Tests** Tests include tools such as sslscan, ssh-audit or cryptolizer which scan a server in order to retrieve the cryptography algorithms and protocols it supports or offers. Results can be used to build a database of effective configurations that will serve for testsuite and documentation purposes. Tests are immediately useful as they help prevent regressions and help us know the current behaviors better. * Benefit: gain confidence in what the tool does * Risk: none * Cost: average for the infrastructure and low to average for each package but multiplied by the number of packages even though some tests could be shared (e.g. sslscan for every http daemon) * Note: don't try perfect coverage as that would require too much time * Batch: all batches ### **System administration tool** Once there are alternative configuration sets, the tool becomes useful * Benefit: none at that point * Risk: none since it is not being used * Cost: low because the MVP code is very small simple and the rest is bigger but still simple * Batch: 1 ### **Crypto configuration split to separate files** Move the relevant configuration entries to separate files in the proper location and refer to them through ‘include’ directives * Benefit: immediately more readable * Risk: low since no configuration change is expected and we have tests * Cost: small for each package but many packages to handle; however there is no requirement to do everything at once * Cost: if we can not get Debian on board to follow this might cause quite some additional regular maintenance/merge/update effort due to the delta that we have to carry for as long as we want to support this solution. * Batch: all batches * Potential order of porting (detailed schedule to be done as part of usual planning tasks): 1. Crypto providers that aren’t crypto users: openssl, gnutls, … 2. HTTPS servers (nginx, apache, lighttpd) not in Rust, Go or Java 3. HTTPS servers but also including some in Rust, Go or Java 4. Virtualization (encryption of guest management via libvirt, encryption of migration, encryption of things on disk with luks, ...) to be of interest to e.g. disable a particular set of algorithms. 5. VPN everything (tend to be quite complex) 6. Everything else ### **Alternative profiles** Design and provide our first alternatives and ensure everything of interest is covered * Benefit: possible to begin experimenting * Risk: none since nothing is activated * Cost: low to average for each package; realistically, only around three such file sets will be created and half a dozen at most * Batch: all batches ### **Restrictions through crypto providers** Restrict which configurations can be used by crypto users by acting only on crypto providers * Benefit: more certainty that configuration choices are effective system-wide * Risk: patching some libraries (e.g. openssl) will be needed * Cost: high for packages that require patching (involves analysis, writing the code, ensuring configuration is not broken, ABI isn't changed, and upstreaming the changes) * Batch: starting from batch 2 ### **Configuration sealing** This step involves detecting packages that do not use configuration files and patches to stop this behavior * Benefit: this is a mandatory step to ensure our configuration of the crypto providers is actually in effect * Risk: low to average since it seems to not be an existing concern and Fedora already does it without trouble it seem but patching crypto providers might be required * Cost: low for each package but there will can be several packages to change and the tools will take some time to write and integrate * Batch: starting from batch 3 ## **Annex: relationship with distribution upstreams (Debian) and downstreams (Ubuntu derivatives)** Every modification of a crypto provider or user has a maintenance cost. Most modifications will be small and that cost will correspondingly be low. However, a number of the affected packages are certainly without Ubuntu modification currently and are therefore synced. Introducing changes will require merging the packages from Debian, costing time and attention. The large number of changes is a strong incentive to upstream them. Will Debian generally accept these changes, and what differences will forever remain between the two distributions? ### **Forever differences** Ubuntu and Debian each have their specificities. It is very unlikely they will have the same configurations for cryptography, partly due to the differences with regard to how decisions are made in both distributions. Keep in mind that having different profiles does not mean they cannot be stored in the same place however. There is support in crypto-config for hiding profiles based on criteria, which makes it possible to include both Debian and Ubuntu profiles in Debian but only show the relevant ones at runtime, thus easing inclusion in Debian. ### **Upstreaming changes** The per-package changes rely on dropins which are uncontroversial. The paths they use only make sense when crypto-config is installed. As a consequence, at least the plumbing and minimal UI of crypto-config must be uploaded and maintained in Debian. Since crypto-config doesn't require special treatment or specific changes by itself, this does not cause specific concerns. Even when users do not install crypto-config, Debian maintainers can benefit from several of the [user stories outlined in this document](#user-stories), in particular to express their intent regarding their package's configuration, especially to expose upcoming changes. We must keep in mind that some maintainers will refuse to include such changes, possibly on non-technical grounds. Hopefully, crypto-config's lightness, optionality and non-disruptiveness will alleviate concerns. It should be noted that it will be scrutinized too for its inclusion in Ubuntu main ultimately: crypto-config will first be in universe but be used to configure packages from main and this will work without component-mismatches, proving this will not lead to any kind of covert takeover. ## **Annex: Example report following package install or removal** I made up the file hierarchy: /distro is where the distribution installs its files while /user is where the user can modify files. The profile modification is not supported but this shows it's not a limitation of the script or of the approach but about reconciling them with dpkg. ``` ************************** * APPLICATION STATUS * ************************** installed => nginx removed => lighttpd ************************** * PROFILES STATUS * ************************** distro/crypto-config:default:nginx => distro/crypto-config/default/nginx distro/crypto-config:test1:nginx => distro/crypto-config/default/nginx distro/crypto-config:test2:nginx => distro/crypto-config/default/nginx user/crypto-config:test:nginx => distro/crypto-config/default/nginx ************************** * PROFILE TREES * ************************** distro/crypto-config/test1/nginx -> ../default/nginx distro/crypto-config/test2/nginx -> ../test1/nginx user/crypto-config/test/nginx -> /distro/crypto-config/test2/nginx ``` # **References** [Fedora Packaging Policy for Crypto](https://docs.fedoraproject.org/en-US/packaging-guidelines/CryptoPolicies/) [NIST \- Recommendation for Key Management](https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-57pt1r5.pdf) and especially section 5.6 Guidance for Cryptographic Algorithm and Key-Size Selection [Universal security from bits and mips to pools, lakes – and beyond](https://eprint.iacr.org/2013/635.pdf) by Lenstra et al [TLS versions and ciphers used for inbound SMTP connections at Toronto University](https://utcc.utoronto.ca/~cks/space/blog/spam/TLSExternalTypes-2023-04) crypto-config-0.7.4/docs/demo-script.txt000066400000000000000000000023761476240702600202440ustar00rootroot00000000000000apt() { lxc exec cc-demo -- apt-get -yqq "$@" } initial_setup() { lxc delete -f cc-demo lxc launch ubuntu-daily:oracular cc-demo sleep 3 apt update apt install libssl3t64 lxc exec cc-demo -- add-apt-repository --yes ppa:adrien/crypto-config apt install nginx ssl-cert sslscan crypto-config &>/dev/null lxc exec cc-demo -- sed -i \ -e '/listen .*80 default_server/ s/listen/# listen/' \ -e '/listen .*443 ssl default_server/ s/# //' \ -e '/# include snippets\/snakeoil.conf;/ s/# //' \ /etc/nginx/sites-available/default lxc exec cc-demo -- crypto-config-hijack.sh lxc exec cc-demo -- systemctl restart nginx } initial_setup lxc shell cc-demo # apt add-apt-repository --yes ppa:videolan/master-daily crypto-config switch legacy apt update crypto-config switch future apt update # nginx sslscan --no-color 127.0.0.1 > default crypto-config switch future nginx -t # Change the configuration and force regenerate the certificate sed -i 's/2048/4096/' /usr/share/ssl-cert/ssleay.cnf && make-ssl-cert -f generate-default-snakeoil && systemctl restart nginx && sslscan --no-color 127.0.0.1 > future view -d default future # under the hood view $(which crypto-config-hijack.sh) ls -lhR --color /var/lib/crypto-config | grep -C99 /usr crypto-config-0.7.4/docs/genesis.md000066400000000000000000000113001476240702600172170ustar00rootroot00000000000000# Crypto-config - a framework for system-wide configuration of cryptography Cryptography is used pervasively in all computers. It protects data in-transit or at rest and guarantees its authenticity; it includes many algorithms and protocols with active research to break and improve them. Decades of research have resulted in numerous improvements but also in the discovery or exploitation of major flaws and limitations. The ciphers used in the 90s are wildly inappropriate today and the ciphers used today were at best brand new in the 90s. With all these changes, it is probably no surprise to find systems with very different configurations, sometimes with outdated cryptography or, on the opposite, unable to use modern cryptography. This often happens even between various software of a single machine. Indeed, nothing guarantees that OpenSSL and GnuTLS are configured the same, or that Apache and MariaDB are either. There can be as many different configurations as there are users of cryptography. ## Actual deployment of modern cryptography hampered by minor differences Several years ago, I started using XMPP and setup a personal server that I configured with modern cryptography and according to best practices. I ensured that my clients communicated well with it too and everything seemed well. Except for one thing: XMPP is a federation of servers and I soon found out that I couldn't communicate with the server of a friend. Both of use were using different software which could use elliptic curves cryptography but weren't using the same curve. I had to switch to a more lenient configuration on my machine while working with upstreams to have the two software support several curves. This was conceptually a very simple issue: two major server implementations each offered modern cryptography but not one that could actually be used reliably. Compound this with how long it takes for updates to propagate and you're looking at least at several years of incompatibility when such differences happen. ## crypto-config The difference above can stem either from code or configuration and it is unfortunately not an isolated issue but closer to the norm currently. Compared to Nginx, we see that Apache doesn't offer AES128 for TLS 1.2. We also see that Postgres only uses P-256. MariaDB doesn't offer CCM mode while mysql doesn't offer ChaCha20-Poly1305. The list is endless. These differences are not security issues today but they make hardening, consistency, compliance, analysis and progress more difficult. Ubuntu's crypto-config framework tackle these issues by providing consistent configuration profiles that are easy to select from. It operates at the level of single machines but once you're using the same configuration profile everywhere, you can be confident that all your clients and servers can communicate together in a safe and modern manner. Every piece of software enrolled in the framework reads configuration dropins which are managed by crypto-config and are changed atomically upon changing profile. While we value consistency, we are also taking into account the different needs of different services and applications. For instance, a mail server or an HTTP client are unlikely to only use the most modern cryptography due to interoperability constraints but a web server where the user base is known (e.g. mobile-only or internal machines) can move forward more easily. Crypto-config will also help us continue to improve the security of Ubuntu by making these configurations explicit and visible for everyone to analyze. ## Moving security forward ## Other systems We are aware of RedHat' crypto-policies that was created years ago; it helped start discussing this topic for Ubuntu. After carefully analyzing crypto-policies, we determined that the initial effort involved in adopting it was at least as large as the effort to develop crypto-config while also incurring on-going costs due to large differences between distributions. We also identified aspects that we deemed too complex for the actual needs and wanted a simpler design that could also be more easily adopted by other distributions that may wish to do so. A major technical difference is that crypto-policies relies on a configuration generator that needs to be implemented for each and every software being configured while crypto-config uses static files which are written by package maintainers. We believe our approach is simpler to integrate in the distribution, especially with a large number of packages to deal with. Finally, crypto-policies is good at making a system comply with a rule such as a given cipher being forbidden. However it doesn't appear to be the best fit for also moving the cryptography of some components further forward like crypto-config does. crypto-config-0.7.4/docs/lxd-cloud-config/000077500000000000000000000000001476240702600204035ustar00rootroot00000000000000crypto-config-0.7.4/docs/lxd-cloud-config/lxd-cloud-config.sh000077500000000000000000000022321476240702600240770ustar00rootroot00000000000000#!/bin/bash set -e set -u crypto_config_profile="${1:-default}" echo 'Clean previous data' lxc delete -f cc-test 2>/dev/null || true lxc profile create cc-test 2>/dev/null || true echo "Set crypto-config profile in cloud-init's user-data.yaml" sed "s/{crypto_config_profile}/${crypto_config_profile}/" user-data.yaml \ | lxc profile set cc-test user.user-data - echo 'Start a container using the cloud-init profile' lxc launch ubuntu-daily:plucky cc-test -p default -p cc-test echo 'Wait for the container to have networking' ipv4='' while ! [[ "$ipv4" =~ 172* ]]; do ipv4="$(lxc list --format json cc-test | jq -r '.[0].state.network.eth0.addresses[0].address')" sleep 1 done echo 'Wait for the web server to serve requests' while ! curl -s -k "https://$ipv4" >/dev/null; do sleep 1; done sslscan "$ipv4" # It seems that exim listens on interfaces which are identified by their IP # rather than by their name... lxc exec cc-test -- sh -c 'sed -i "/dc_local_interfaces/ s/;/; $(ip -4 --json a s dev eth0 | jq -r ".[0].addr_info[0].local");/" /etc/exim4/update-exim4.conf.conf' lxc exec cc-test systemctl restart exim4 sslscan --starttls-smtp --sleep=60 "$ipv4" crypto-config-0.7.4/docs/lxd-cloud-config/user-data-clean.yaml000066400000000000000000000002501476240702600242310ustar00rootroot00000000000000#cloud-config package_update: true package_upgrade: true packages: - crypto-config - nginx - ssl-cert runcmd: - crypto-config switch {crypto_config_profile} crypto-config-0.7.4/docs/lxd-cloud-config/user-data.yaml000066400000000000000000000015061476240702600231560ustar00rootroot00000000000000#cloud-config package_update: true package_upgrade: true packages: - crypto-config - exim4 - nginx - ssl-cert runcmd: - sed -i -e '/listen .*80 default_server/ s/listen/# listen/' -e '/listen .*443 ssl default_server/ s/# //' -e '/# include snippets\/snakeoil.conf;/ s/# //' /etc/nginx/sites-available/default - sed -i '/ssl_protocols/ d' '/etc/nginx/nginx.conf' - echo 'include /var/lib/crypto-config/profiles/current/nginx.conf.d/*.conf;' > '/etc/nginx/conf.d/crypto-config.conf' - sed -i 's/2048/4096/' '/usr/share/ssl-cert/ssleay.cnf' - make-ssl-cert -f generate-default-snakeoil - sed -i '/Defines what/ i .include_if_exists /var/lib/crypto-config/profiles/current/exim' /etc/exim4/exim4.conf.template - crypto-config switch {crypto_config_profile} - crypto-config status - systemctl restart exim4 nginx crypto-config-0.7.4/docs/release.md000066400000000000000000000007021476240702600172060ustar00rootroot00000000000000# Prepare a release for github and sign it Generate tarball with ``` tag=0.7.2 tarball="../crypto-config_${tag}.orig.tar.gz" git tag -m "${tag}" -s "v${tag}" git -c tar.tar.gz.command='gzip -cn' archive --format=tar.gz --prefix="crypto-config-${tag}/" -o "${tarball}" "v${tag}" gpg --armor --detach-sign "${tarball}" gpg --verify "${tarball}.asc" ``` Push the tag. From the github.com UI, create a release with the .asc file uploaded crypto-config-0.7.4/lxd-profile000066400000000000000000000032521476240702600164670ustar00rootroot00000000000000devices: proxy-80-v4: connect: tcp:127.0.0.1:80 listen: tcp:0.0.0.0:80 type: proxy proxy-443-v4: connect: tcp:127.0.0.1:443 listen: tcp:0.0.0.0:443 type: proxy # proxy-80-v6: # connect: tcp:[::1]:80 # listen: tcp:[::]:80 # type: proxy # proxy-443-v6: # connect: tcp:[::1]:443 # listen: tcp:[::]:443 # type: proxy config: cloud-init.user-data: | #cloud-config apt: sources: crypto-config-ppa: source: "ppa:adrien/crypto-config" package_update: true package_upgrade: true packages: - nginx - certbot - crypto-config runcmd: - apt-get update - apt-get install -y nginx certbot crypto-config - crypto-config future - certbot certonly --standalone --pre-hook 'systemctl stop nginx' --post-hook 'systemctl start nginx' --agree-tos --preferred-challenges http -d mantic-cc.dcln.fr -d m.dcln.fr -m adrien@notk.org -n --test-cert # - a2enmod ssl # - a2ensite default-ssl - sed -i '/443 ssl default_server/ s/# //' /etc/nginx/sites-available/default - sed -i '/replace_domain/ { s/replace_domain/m.dcln.fr/ ; s/# // }' /etc/nginx/sites-available/default # - sed -i '/replace_domain/ { s/replace_domain/m.dcln.fr/ ; s/# // }' /etc/apache2/sites-available/default-ssl.conf - systemctl restart nginx # lxc profile create tls # for port in 80 443; do # lxc profile device add tls proxy-${port}-v4 proxy "listen=tcp:0.0.0.0:${port}" connect="tcp:127.0.0.1:${port}" # lxc profile device add tls proxy-${port}-v6 proxy "listen=tcp:[::]:${port}" connect="tcp:[::1]:${port}" # done # lxc launch ubuntu-daily:mantic mantic --profile tls crypto-config-0.7.4/man/000077500000000000000000000000001476240702600150705ustar00rootroot00000000000000crypto-config-0.7.4/man/crypto-config.1.adoc000066400000000000000000000013521476240702600206430ustar00rootroot00000000000000= crypto-config(1) :author: Adrien Nader :email: adrien.nader@canonical.com :revdate: 2025-02-21 :revnumber: v0.7.3 :doctype: manpage :manmanual: crypto-config :mansource: crypto-config == Name crypto-config - display and manage crypto-config profiles == Synopsis *crypto-config* [_COMMAND_]... == Commands *get*:: Return the profile currently in use. *status*:: Show the profile currently in use. May show more in the future. This is meant for interactive use rather than for scripting. *switch* _PROFILE_:: Use this profile. == Resources *Web site:* https://github.com/canonical/crypto-config == Copying Copyright (C) 2023-2025 Canonical, Ltd This software is released under the terms of the GNU General Public License, Version 3. crypto-config-0.7.4/profiles/000077500000000000000000000000001476240702600161405ustar00rootroot00000000000000crypto-config-0.7.4/profiles/debian/000077500000000000000000000000001476240702600173625ustar00rootroot00000000000000crypto-config-0.7.4/profiles/debian/test1/000077500000000000000000000000001476240702600204225ustar00rootroot00000000000000crypto-config-0.7.4/profiles/debian/test1/metadata.json000066400000000000000000000003321476240702600230730ustar00rootroot00000000000000{ "pretty-name": "test1", "summary": "A profile stored in a sub-directory as a demo", "description": "", "maintainer": "Maintainers of the crypto-config package", "parent": "default", "condition": "true" } crypto-config-0.7.4/profiles/default/000077500000000000000000000000001476240702600175645ustar00rootroot00000000000000crypto-config-0.7.4/profiles/default/apt.conf.d/000077500000000000000000000000001476240702600215165ustar00rootroot00000000000000crypto-config-0.7.4/profiles/default/apt.conf.d/assert-pubkey-algo.conf000066400000000000000000000000001476240702600260710ustar00rootroot00000000000000crypto-config-0.7.4/profiles/default/exim000066400000000000000000000000001476240702600204370ustar00rootroot00000000000000crypto-config-0.7.4/profiles/default/gnutls.conf000066400000000000000000000001661476240702600217520ustar00rootroot00000000000000[overrides] disabled-version = tls1.0 disabled-version = tls1.1 disabled-version = dtls0.9 disabled-version = dtls1.0 crypto-config-0.7.4/profiles/default/metadata.json000066400000000000000000000003021476240702600222320ustar00rootroot00000000000000{ "pretty-name": "default", "summary": "The default profile", "description": "", "maintainer": "Maintainers of the crypto-config package", "parent": "default", "condition": "true" } crypto-config-0.7.4/profiles/default/nginx.conf.d/000077500000000000000000000000001476240702600220555ustar00rootroot00000000000000crypto-config-0.7.4/profiles/default/nginx.conf.d/ssl.conf000066400000000000000000000000371476240702600235250ustar00rootroot00000000000000ssl_protocols TLSv1.2 TLSv1.3; crypto-config-0.7.4/profiles/default/openssl.conf.d/000077500000000000000000000000001476240702600224155ustar00rootroot00000000000000crypto-config-0.7.4/profiles/default/openssl.conf.d/empty.cnf000066400000000000000000000001451476240702600242430ustar00rootroot00000000000000# This is an empty file so that the directory is not empty and so that dh_install does not remove it crypto-config-0.7.4/profiles/future/000077500000000000000000000000001476240702600174525ustar00rootroot00000000000000crypto-config-0.7.4/profiles/future/apt.conf.d/000077500000000000000000000000001476240702600214045ustar00rootroot00000000000000crypto-config-0.7.4/profiles/future/apt.conf.d/assert-pubkey-algo.conf000066400000000000000000000000561476240702600257720ustar00rootroot00000000000000APT::Key::Assert-Pubkey-Algo >=ed25519,ed448; crypto-config-0.7.4/profiles/future/exim000066400000000000000000000002511476240702600203350ustar00rootroot00000000000000tls_eccurve = X25519:prime256v1:secp384r1:secp521r1 tls_require_ciphers = PFS:-SHA1:-GROUP-FFDHE2048:-GROUP-FFDHE3072:-GROUP-FFDHE4096:-GROUP-FFDHE6144:-GROUP-FFDHE8192 crypto-config-0.7.4/profiles/future/metadata.json000066400000000000000000000003371476240702600221300ustar00rootroot00000000000000{ "pretty-name": "future", "summary": "This profile will be used in future releases", "description": "", "maintainer": "Maintainers of the crypto-config package", "parent": "like-default", "condition": "true" } crypto-config-0.7.4/profiles/future/openssl.conf.d/000077500000000000000000000000001476240702600223035ustar00rootroot00000000000000crypto-config-0.7.4/profiles/future/openssl.conf.d/seclevel.cnf000066400000000000000000000002501476240702600245720ustar00rootroot00000000000000[ openssl_init ] ssl_conf = ssl_sect [ssl_sect] system_default = system_default_sect [system_default_sect] MinProtocol = TLSv1.3 CipherString = DEFAULT:@SECLEVEL=3 crypto-config-0.7.4/profiles/legacy/000077500000000000000000000000001476240702600174045ustar00rootroot00000000000000crypto-config-0.7.4/profiles/legacy/apt.conf.d/000077500000000000000000000000001476240702600213365ustar00rootroot00000000000000crypto-config-0.7.4/profiles/legacy/apt.conf.d/assert-pubkey-algo.conf000066400000000000000000000000661476240702600257250ustar00rootroot00000000000000APT::Key::Assert-Pubkey-Algo >=rsa1024,ed25519,ed448; crypto-config-0.7.4/profiles/legacy/metadata.json000066400000000000000000000003331476240702600220560ustar00rootroot00000000000000{ "pretty-name": "legacy", "summary": "Profile for compatibility with legacy systems", "description": "", "maintainer": "Maintainers of the crypto-config package", "parent": "default", "condition": "true" } crypto-config-0.7.4/profiles/legacy/openssl.conf.d/000077500000000000000000000000001476240702600222355ustar00rootroot00000000000000crypto-config-0.7.4/profiles/legacy/openssl.conf.d/seclevel.cnf000066400000000000000000000003041476240702600245240ustar00rootroot00000000000000[ default_conf ] openssl_init = ssl_sect [ssl_sect] system_default = system_default_sect [system_default_sect] MinProtocol = TLSv1.0 TLSv1.1 TLSv1.2 TLSv1.3 CipherString = DEFAULT:@SECLEVEL=1 crypto-config-0.7.4/profiles/like-default/000077500000000000000000000000001476240702600205065ustar00rootroot00000000000000crypto-config-0.7.4/profiles/like-default/metadata.json000066400000000000000000000003211476240702600231550ustar00rootroot00000000000000{ "pretty-name": "like-default", "summary": "A copy of the default profile", "description": "", "maintainer": "Maintainers of the crypto-config package", "parent": "default", "condition": "true" } crypto-config-0.7.4/src/000077500000000000000000000000001476240702600151045ustar00rootroot00000000000000crypto-config-0.7.4/src/crypto-config000077500000000000000000000145171476240702600176250ustar00rootroot00000000000000#!/bin/bash # # Copyright (C) 2023-2024 Canonical, Ltd. # Author: Adrien Nader # # 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; version 3. # # 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, see . set -e set -u shopt -s inherit_errexit DESTDIR="${DESTDIR:-}" DEFAULT_PROFILE='default' DATA_DIR="${DESTDIR}/usr/share/crypto-config" SYSTEM_PROFILES_DIR="${DATA_DIR}/profiles" # USER_PROFILES='user/crypto-config' # ALL_PROFILES="${SYSTEM_PROFILES_DIR} ${USER_PROFILES}" ALL_PROFILES="${SYSTEM_PROFILES_DIR}" STATE_DIR="${DESTDIR}/var/lib/crypto-config" STATE_PROFILES_DIR="${STATE_DIR}/profiles" verbose='false' CURRENT="${STATE_PROFILES_DIR}/current" log() { if "${verbose}"; then echo "$@" fi } dirs_in() { # Output the list of directories directly inside a given directory # Depth limit is 2. It was 1 in order to avoid picking applications' # directories but 2 is useful to be able to use "debian/foo" or "ubuntu/bar". # It could be higher once we can make sure 'metadata.json' is really for # crypto-config and not a random file with the same name. find "${1}" -mindepth 1 -maxdepth 2 -type d -printf '%P\n' } entries_in() { # Output the directory entries directly inside a given directory find "${1}" -mindepth 1 -maxdepth 1 -printf '%P\n' } _list_profiles_and_parent() { # Output a list of profiles and their parent in the following format: # profile1_parent profile1 # profile2_parent profile2 local profile_dir profile_dir="$1" for profile in $(dirs_in "${profile_dir}"); do # Ensure we only iterate on directories which can be valid profiles if [[ "${profile}" != 'default' ]] && ! [[ -e "${profile_dir}/${profile}/metadata.json" ]]; then continue fi # TODO: switch to the 'metadata.json' file rather than 'parent' jq -r '"\(.parent) '"${profile}"'"' < "${profile_dir}/${profile}/metadata.json" done } _reach_state() { local profile_dir local profile local apps profile_dir="${1}" profile="${2}" shift 2 apps=("$@") # Skip profiles that don't exist in the current profile directory # This is because shell script makes it a fair bit difficult to do the # topological sort on profile names and keep track of which directory # they come from. if ! [[ -e "${profile_dir}/${profile}" ]]; then return fi log " - Profile: ${profile}" # The default profile has no parent by definition and does not need to be # modified since it is the single source of truth if [[ "${profile}" = "${DEFAULT_PROFILE}" ]]; then log " - source of truth" # Symlink to the directory where the profile lives: it is required to be # complete already, therefore we can use it directly ln -sfn "${profile_dir}/${profile}" "${STATE_PROFILES_DIR}/${profile}" return fi # Ensure the profile directory exists in the state directory mkdir -p "${STATE_PROFILES_DIR}/${profile}" # Due to the call to tsort we couldn't easily keep the information on # where the profiles reside. Recover that. parent_profile="$(jq -r '.parent' < "${profile_dir}/${profile}/metadata.json")" for app in "${apps[@]}"; do if [[ -z "${app}" ]]; then continue fi link="${STATE_PROFILES_DIR}/${profile}/${app}" # If app profile exists in the current profile, use it. # If not, if app profile exists in the parent profile, create a symlink to # there. # If it doesn't either, remove any existing symlink as there is no matching # profile available anymore. target="${profile_dir}/${profile}/${app}" if [[ -e "${target}" ]]; then log " - ${app}: link to ${target}" ln -sfn "${target}" "${link}" continue fi target="${STATE_PROFILES_DIR}/${parent_profile}/${app}" if [[ -e "${target}" ]]; then log " - ${app}: link to ${target}" ln -sfn "${target}" "${link}" continue fi if [[ -e "${link}" ]] || [[ -L "${link}" ]]; then log " - ${app}: remove" else log " - ${app}: absent" fi rm -f "${link}" done # TODO: remove profiles that have been removed } _update_profile() { local profile_dir local apps profile_dir="${1}" shift apps=("$@") if ! [[ -d "${profile_dir}" ]]; then return fi log "- Profile dir: ${profile_dir}" # TODO: profile names must be unique across profile directories _list_profiles_and_parent "${profile_dir}" \ | tsort \ | while read -r profile; do _reach_state "${profile_dir}" "${profile}" "${apps[@]}" done } generate_runtime_profiles() { mkdir -p "${STATE_PROFILES_DIR}" mapfile -t apps < <(entries_in "${SYSTEM_PROFILES_DIR}/${DEFAULT_PROFILE}") for profile_dir in ${ALL_PROFILES}; do _update_profile "${profile_dir}" "${apps[@]}" done # Make 'current' point to 'default' if it doesn't exist or points to a # non-existant file (works because -e uses stat(), not lstat()) if ! [[ -e "${STATE_PROFILES_DIR}/current" ]]; then ln -sfn 'default' "${STATE_PROFILES_DIR}/current" fi } help() { cat << EOF Usage: crypto-config ... System-wide cryptography configuration profile management User commands: get-current status switch Plumbing: generate-runtime-profiles EOF } switch() { local target target="$1" if ! [[ -d "${STATE_PROFILES_DIR}/$1" ]]; then echo "'${target}' does not exist or is not a directory." exit 1 fi ln -sfn "${target}" "${CURRENT}" echo "Profile switched to '${target}'." } get_current() { basename "$(readlink "${CURRENT}")" } status() { local current current="$(get_current)" printf "Current profile in '%s'\n" "${current}" } case "${1:-help}" in -h|-help|--help|help|h) help ;; generate-runtime-profiles) shift generate_runtime_profiles ;; get-current) shift get_current ;; status) shift status ;; switch) shift switch "$@" ;; *) printf "Unknown command '%s'\n" "$1" help ;; esac crypto-config-0.7.4/status.sh000066400000000000000000000023551476240702600162010ustar00rootroot00000000000000cat << EOF ************************** * PROFILES STATUS * ************************** EOF for profile_dir in "${DESTDIR}${DISTRO_PROFILES}" "${DESTDIR}${USER_PROFILES}"; do for profile in $(dirs_in "${profile_dir}"); do profile="$(basename "${profile}")" for app in ${apps}; do if is_removed "${app}"; then continue fi link="${profile_dir}/${profile}/${app}" if target="$(realpath --relative-to="${DESTDIR}" "${link}" 2>/dev/null)"; then target_canonical="$(realpath --canonicalize-existing --relative-to="${DESTDIR}" "${link}")" if [ "${target}" = "${target_canonical}" ]; then echo "${profile_dir/${DESTDIR}}:${profile}:${app} => ${target}" else echo "${profile_dir/${DESTDIR}}:${profile}:${app} => ${target} => ${target_canonical}" fi else echo ${profile_dir}:"${profile}:${app} absent" fi done done done | sort | uniq | column -t cat << EOF ************************** * PROFILE TREES * ************************** EOF ( if [ -n "${DESTDIR}" ]; then cd "${DESTDIR}" fi find "${DISTRO_PROFILES}" "${USER_PROFILES}" \( -type f -name parent \) -o \( -type l -o -type f \) -exec ls --color -oh {} + )