pax_global_header 0000666 0000000 0000000 00000000064 14762407026 0014522 g ustar 00root root 0000000 0000000 52 comment=be74bd56296ca6b9e0d7fad5f963d46534e9afe0
crypto-config-0.7.4/ 0000775 0000000 0000000 00000000000 14762407026 0014315 5 ustar 00root root 0000000 0000000 crypto-config-0.7.4/.gitignore 0000664 0000000 0000000 00000000071 14762407026 0016303 0 ustar 00root root 0000000 0000000 *~
*.sw[po]
/target/
/Cargo.*
src/main.rs
debian/files
crypto-config-0.7.4/CHANGELOG.md 0000664 0000000 0000000 00000001701 14762407026 0016125 0 ustar 00root root 0000000 0000000 # 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/COPYING 0000664 0000000 0000000 00000104513 14762407026 0015354 0 ustar 00root root 0000000 0000000 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/Makefile 0000664 0000000 0000000 00000000174 14762407026 0015757 0 ustar 00root root 0000000 0000000 all: 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.md 0000664 0000000 0000000 00000020540 14762407026 0015575 0 ustar 00root root 0000000 0000000 # 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/ 0000775 0000000 0000000 00000000000 14762407026 0015537 5 ustar 00root root 0000000 0000000 crypto-config-0.7.4/debian/changelog 0000664 0000000 0000000 00000000524 14762407026 0017412 0 ustar 00root root 0000000 0000000 crypto-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/control 0000664 0000000 0000000 00000001632 14762407026 0017144 0 ustar 00root root 0000000 0000000 Source: 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/copyright 0000664 0000000 0000000 00000001075 14762407026 0017475 0 ustar 00root root 0000000 0000000 Format: 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.install 0000664 0000000 0000000 00000000110 14762407026 0021702 0 ustar 00root root 0000000 0000000 profiles/* usr/share/crypto-config/profiles/
src/crypto-config usr/bin/
crypto-config-0.7.4/debian/crypto-config.manpages 0000664 0000000 0000000 00000000024 14762407026 0022033 0 ustar 00root root 0000000 0000000 man/crypto-config.1
crypto-config-0.7.4/debian/crypto-config.postinst 0000775 0000000 0000000 00000001660 14762407026 0022135 0 ustar 00root root 0000000 0000000 #!/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.triggers 0000664 0000000 0000000 00000000063 14762407026 0022071 0 ustar 00root root 0000000 0000000 interest-noawait /usr/share/crypto-config/profiles
crypto-config-0.7.4/debian/rules 0000775 0000000 0000000 00000000066 14762407026 0016621 0 ustar 00root root 0000000 0000000 #!/usr/bin/make -f
#export DH_VERBOSE = 1
%:
dh $@
crypto-config-0.7.4/debian/source/ 0000775 0000000 0000000 00000000000 14762407026 0017037 5 ustar 00root root 0000000 0000000 crypto-config-0.7.4/debian/source/format 0000664 0000000 0000000 00000000014 14762407026 0020245 0 ustar 00root root 0000000 0000000 3.0 (quilt)
crypto-config-0.7.4/debian/source/options 0000664 0000000 0000000 00000000105 14762407026 0020451 0 ustar 00root root 0000000 0000000 extend-diff-ignore = "^(target/.*|Cargo\.(lock|toml)|src/main\.rs)$"
crypto-config-0.7.4/debian/upstream/ 0000775 0000000 0000000 00000000000 14762407026 0017377 5 ustar 00root root 0000000 0000000 crypto-config-0.7.4/debian/upstream/signing-key.asc 0000664 0000000 0000000 00000012452 14762407026 0022317 0 ustar 00root root 0000000 0000000 -----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/watch 0000664 0000000 0000000 00000000400 14762407026 0016562 0 ustar 00root root 0000000 0000000 version=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/ 0000775 0000000 0000000 00000000000 14762407026 0015245 5 ustar 00root root 0000000 0000000 crypto-config-0.7.4/docs/crypto-config-specification.md 0000664 0000000 0000000 00000223771 14762407026 0023204 0 ustar 00root root 0000000 0000000 NB: 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.txt 0000664 0000000 0000000 00000002376 14762407026 0020244 0 ustar 00root root 0000000 0000000 apt() {
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.md 0000664 0000000 0000000 00000011300 14762407026 0017217 0 ustar 00root root 0000000 0000000 # 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/ 0000775 0000000 0000000 00000000000 14762407026 0020403 5 ustar 00root root 0000000 0000000 crypto-config-0.7.4/docs/lxd-cloud-config/lxd-cloud-config.sh 0000775 0000000 0000000 00000002232 14762407026 0024077 0 ustar 00root root 0000000 0000000 #!/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.yaml 0000664 0000000 0000000 00000000250 14762407026 0024231 0 ustar 00root root 0000000 0000000 #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.yaml 0000664 0000000 0000000 00000001506 14762407026 0023156 0 ustar 00root root 0000000 0000000 #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.md 0000664 0000000 0000000 00000000702 14762407026 0017206 0 ustar 00root root 0000000 0000000 # 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-profile 0000664 0000000 0000000 00000003252 14762407026 0016467 0 ustar 00root root 0000000 0000000 devices:
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/ 0000775 0000000 0000000 00000000000 14762407026 0015070 5 ustar 00root root 0000000 0000000 crypto-config-0.7.4/man/crypto-config.1.adoc 0000664 0000000 0000000 00000001352 14762407026 0020643 0 ustar 00root root 0000000 0000000 = 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/ 0000775 0000000 0000000 00000000000 14762407026 0016140 5 ustar 00root root 0000000 0000000 crypto-config-0.7.4/profiles/debian/ 0000775 0000000 0000000 00000000000 14762407026 0017362 5 ustar 00root root 0000000 0000000 crypto-config-0.7.4/profiles/debian/test1/ 0000775 0000000 0000000 00000000000 14762407026 0020422 5 ustar 00root root 0000000 0000000 crypto-config-0.7.4/profiles/debian/test1/metadata.json 0000664 0000000 0000000 00000000332 14762407026 0023073 0 ustar 00root root 0000000 0000000 {
"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/ 0000775 0000000 0000000 00000000000 14762407026 0017564 5 ustar 00root root 0000000 0000000 crypto-config-0.7.4/profiles/default/apt.conf.d/ 0000775 0000000 0000000 00000000000 14762407026 0021516 5 ustar 00root root 0000000 0000000 crypto-config-0.7.4/profiles/default/apt.conf.d/assert-pubkey-algo.conf 0000664 0000000 0000000 00000000000 14762407026 0026071 0 ustar 00root root 0000000 0000000 crypto-config-0.7.4/profiles/default/exim 0000664 0000000 0000000 00000000000 14762407026 0020437 0 ustar 00root root 0000000 0000000 crypto-config-0.7.4/profiles/default/gnutls.conf 0000664 0000000 0000000 00000000166 14762407026 0021752 0 ustar 00root root 0000000 0000000 [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.json 0000664 0000000 0000000 00000000302 14762407026 0022232 0 ustar 00root root 0000000 0000000 {
"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/ 0000775 0000000 0000000 00000000000 14762407026 0022055 5 ustar 00root root 0000000 0000000 crypto-config-0.7.4/profiles/default/nginx.conf.d/ssl.conf 0000664 0000000 0000000 00000000037 14762407026 0023525 0 ustar 00root root 0000000 0000000 ssl_protocols TLSv1.2 TLSv1.3;
crypto-config-0.7.4/profiles/default/openssl.conf.d/ 0000775 0000000 0000000 00000000000 14762407026 0022415 5 ustar 00root root 0000000 0000000 crypto-config-0.7.4/profiles/default/openssl.conf.d/empty.cnf 0000664 0000000 0000000 00000000145 14762407026 0024243 0 ustar 00root root 0000000 0000000 # 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/ 0000775 0000000 0000000 00000000000 14762407026 0017452 5 ustar 00root root 0000000 0000000 crypto-config-0.7.4/profiles/future/apt.conf.d/ 0000775 0000000 0000000 00000000000 14762407026 0021404 5 ustar 00root root 0000000 0000000 crypto-config-0.7.4/profiles/future/apt.conf.d/assert-pubkey-algo.conf 0000664 0000000 0000000 00000000056 14762407026 0025772 0 ustar 00root root 0000000 0000000 APT::Key::Assert-Pubkey-Algo >=ed25519,ed448;
crypto-config-0.7.4/profiles/future/exim 0000664 0000000 0000000 00000000251 14762407026 0020335 0 ustar 00root root 0000000 0000000 tls_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.json 0000664 0000000 0000000 00000000337 14762407026 0022130 0 ustar 00root root 0000000 0000000 {
"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/ 0000775 0000000 0000000 00000000000 14762407026 0022303 5 ustar 00root root 0000000 0000000 crypto-config-0.7.4/profiles/future/openssl.conf.d/seclevel.cnf 0000664 0000000 0000000 00000000250 14762407026 0024572 0 ustar 00root root 0000000 0000000 [ 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/ 0000775 0000000 0000000 00000000000 14762407026 0017404 5 ustar 00root root 0000000 0000000 crypto-config-0.7.4/profiles/legacy/apt.conf.d/ 0000775 0000000 0000000 00000000000 14762407026 0021336 5 ustar 00root root 0000000 0000000 crypto-config-0.7.4/profiles/legacy/apt.conf.d/assert-pubkey-algo.conf 0000664 0000000 0000000 00000000066 14762407026 0025725 0 ustar 00root root 0000000 0000000 APT::Key::Assert-Pubkey-Algo >=rsa1024,ed25519,ed448;
crypto-config-0.7.4/profiles/legacy/metadata.json 0000664 0000000 0000000 00000000333 14762407026 0022056 0 ustar 00root root 0000000 0000000 {
"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/ 0000775 0000000 0000000 00000000000 14762407026 0022235 5 ustar 00root root 0000000 0000000 crypto-config-0.7.4/profiles/legacy/openssl.conf.d/seclevel.cnf 0000664 0000000 0000000 00000000304 14762407026 0024524 0 ustar 00root root 0000000 0000000 [ 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/ 0000775 0000000 0000000 00000000000 14762407026 0020506 5 ustar 00root root 0000000 0000000 crypto-config-0.7.4/profiles/like-default/metadata.json 0000664 0000000 0000000 00000000321 14762407026 0023155 0 ustar 00root root 0000000 0000000 {
"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/ 0000775 0000000 0000000 00000000000 14762407026 0015104 5 ustar 00root root 0000000 0000000 crypto-config-0.7.4/src/crypto-config 0000775 0000000 0000000 00000014517 14762407026 0017625 0 ustar 00root root 0000000 0000000 #!/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.sh 0000664 0000000 0000000 00000002355 14762407026 0016201 0 ustar 00root root 0000000 0000000 cat << 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 {} +
)