forked from pool/pesign-obs-integration
osc copypac from project:home:michal-m:modsign package:pesign-obs-integration revision:2
OBS-URL: https://build.opensuse.org/package/show/Base:System/pesign-obs-integration?expand=0&rev=1
This commit is contained in:
commit
184dbd8a83
23
.gitattributes
vendored
Normal file
23
.gitattributes
vendored
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
## Default LFS
|
||||||
|
*.7z filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.bsp filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.bz2 filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.gem filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.gz filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.jar filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.lz filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.lzma filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.obscpio filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.oxt filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.pdf filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.png filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.rpm filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.tbz filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.tbz2 filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.tgz filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.ttf filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.txz filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.whl filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.xz filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.zip filter=lfs diff=lfs merge=lfs -text
|
||||||
|
*.zst filter=lfs diff=lfs merge=lfs -text
|
1
.gitignore
vendored
Normal file
1
.gitignore
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
.osc
|
339
COPYING
Normal file
339
COPYING
Normal file
@ -0,0 +1,339 @@
|
|||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
Version 2, June 1991
|
||||||
|
|
||||||
|
Copyright (C) 1989, 1991 Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA
|
||||||
|
Everyone is permitted to copy and distribute verbatim copies
|
||||||
|
of this license document, but changing it is not allowed.
|
||||||
|
|
||||||
|
Preamble
|
||||||
|
|
||||||
|
The licenses for most software are designed to take away your
|
||||||
|
freedom to share and change it. By contrast, the GNU General Public
|
||||||
|
License is intended to guarantee your freedom to share and change free
|
||||||
|
software--to make sure the software is free for all its users. This
|
||||||
|
General Public License applies to most of the Free Software
|
||||||
|
Foundation's software and to any other program whose authors commit to
|
||||||
|
using it. (Some other Free Software Foundation software is covered by
|
||||||
|
the GNU Lesser General Public License instead.) You can apply it to
|
||||||
|
your programs, too.
|
||||||
|
|
||||||
|
When we speak of free software, we are referring to freedom, not
|
||||||
|
price. Our General Public Licenses are designed to make sure that you
|
||||||
|
have the freedom to distribute copies of free software (and charge for
|
||||||
|
this service if you wish), that you receive source code or can get it
|
||||||
|
if you want it, that you can change the software or use pieces of it
|
||||||
|
in new free programs; and that you know you can do these things.
|
||||||
|
|
||||||
|
To protect your rights, we need to make restrictions that forbid
|
||||||
|
anyone to deny you these rights or to ask you to surrender the rights.
|
||||||
|
These restrictions translate to certain responsibilities for you if you
|
||||||
|
distribute copies of the software, or if you modify it.
|
||||||
|
|
||||||
|
For example, if you distribute copies of such a program, whether
|
||||||
|
gratis or for a fee, you must give the recipients all the rights that
|
||||||
|
you have. You must make sure that they, too, receive or can get the
|
||||||
|
source code. And you must show them these terms so they know their
|
||||||
|
rights.
|
||||||
|
|
||||||
|
We protect your rights with two steps: (1) copyright the software, and
|
||||||
|
(2) offer you this license which gives you legal permission to copy,
|
||||||
|
distribute and/or modify the software.
|
||||||
|
|
||||||
|
Also, for each author's protection and ours, we want to make certain
|
||||||
|
that everyone understands that there is no warranty for this free
|
||||||
|
software. If the software is modified by someone else and passed on, we
|
||||||
|
want its recipients to know that what they have is not the original, so
|
||||||
|
that any problems introduced by others will not reflect on the original
|
||||||
|
authors' reputations.
|
||||||
|
|
||||||
|
Finally, any free program is threatened constantly by software
|
||||||
|
patents. We wish to avoid the danger that redistributors of a free
|
||||||
|
program will individually obtain patent licenses, in effect making the
|
||||||
|
program proprietary. To prevent this, we have made it clear that any
|
||||||
|
patent must be licensed for everyone's free use or not licensed at all.
|
||||||
|
|
||||||
|
The precise terms and conditions for copying, distribution and
|
||||||
|
modification follow.
|
||||||
|
|
||||||
|
GNU GENERAL PUBLIC LICENSE
|
||||||
|
TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION
|
||||||
|
|
||||||
|
0. This License applies to any program or other work which contains
|
||||||
|
a notice placed by the copyright holder saying it may be distributed
|
||||||
|
under the terms of this General Public License. The "Program", below,
|
||||||
|
refers to any such program or work, and a "work based on the Program"
|
||||||
|
means either the Program or any derivative work under copyright law:
|
||||||
|
that is to say, a work containing the Program or a portion of it,
|
||||||
|
either verbatim or with modifications and/or translated into another
|
||||||
|
language. (Hereinafter, translation is included without limitation in
|
||||||
|
the term "modification".) Each licensee is addressed as "you".
|
||||||
|
|
||||||
|
Activities other than copying, distribution and modification are not
|
||||||
|
covered by this License; they are outside its scope. The act of
|
||||||
|
running the Program is not restricted, and the output from the Program
|
||||||
|
is covered only if its contents constitute a work based on the
|
||||||
|
Program (independent of having been made by running the Program).
|
||||||
|
Whether that is true depends on what the Program does.
|
||||||
|
|
||||||
|
1. You may copy and distribute verbatim copies of the Program's
|
||||||
|
source code as you receive it, in any medium, provided that you
|
||||||
|
conspicuously and appropriately publish on each copy an appropriate
|
||||||
|
copyright notice and disclaimer of warranty; keep intact all the
|
||||||
|
notices that refer to this License and to the absence of any warranty;
|
||||||
|
and give any other recipients of the Program a copy of this License
|
||||||
|
along with the Program.
|
||||||
|
|
||||||
|
You may charge a fee for the physical act of transferring a copy, and
|
||||||
|
you may at your option offer warranty protection in exchange for a fee.
|
||||||
|
|
||||||
|
2. You may modify your copy or copies of the Program or any portion
|
||||||
|
of it, thus forming a work based on the Program, and copy and
|
||||||
|
distribute such modifications or work under the terms of Section 1
|
||||||
|
above, provided that you also meet all of these conditions:
|
||||||
|
|
||||||
|
a) You must cause the modified files to carry prominent notices
|
||||||
|
stating that you changed the files and the date of any change.
|
||||||
|
|
||||||
|
b) You must cause any work that you distribute or publish, that in
|
||||||
|
whole or in part contains or is derived from the Program or any
|
||||||
|
part thereof, to be licensed as a whole at no charge to all third
|
||||||
|
parties under the terms of this License.
|
||||||
|
|
||||||
|
c) If the modified program normally reads commands interactively
|
||||||
|
when run, you must cause it, when started running for such
|
||||||
|
interactive use in the most ordinary way, to print or display an
|
||||||
|
announcement including an appropriate copyright notice and a
|
||||||
|
notice that there is no warranty (or else, saying that you provide
|
||||||
|
a warranty) and that users may redistribute the program under
|
||||||
|
these conditions, and telling the user how to view a copy of this
|
||||||
|
License. (Exception: if the Program itself is interactive but
|
||||||
|
does not normally print such an announcement, your work based on
|
||||||
|
the Program is not required to print an announcement.)
|
||||||
|
|
||||||
|
These requirements apply to the modified work as a whole. If
|
||||||
|
identifiable sections of that work are not derived from the Program,
|
||||||
|
and can be reasonably considered independent and separate works in
|
||||||
|
themselves, then this License, and its terms, do not apply to those
|
||||||
|
sections when you distribute them as separate works. But when you
|
||||||
|
distribute the same sections as part of a whole which is a work based
|
||||||
|
on the Program, the distribution of the whole must be on the terms of
|
||||||
|
this License, whose permissions for other licensees extend to the
|
||||||
|
entire whole, and thus to each and every part regardless of who wrote it.
|
||||||
|
|
||||||
|
Thus, it is not the intent of this section to claim rights or contest
|
||||||
|
your rights to work written entirely by you; rather, the intent is to
|
||||||
|
exercise the right to control the distribution of derivative or
|
||||||
|
collective works based on the Program.
|
||||||
|
|
||||||
|
In addition, mere aggregation of another work not based on the Program
|
||||||
|
with the Program (or with a work based on the Program) on a volume of
|
||||||
|
a storage or distribution medium does not bring the other work under
|
||||||
|
the scope of this License.
|
||||||
|
|
||||||
|
3. You may copy and distribute the Program (or a work based on it,
|
||||||
|
under Section 2) in object code or executable form under the terms of
|
||||||
|
Sections 1 and 2 above provided that you also do one of the following:
|
||||||
|
|
||||||
|
a) Accompany it with the complete corresponding machine-readable
|
||||||
|
source code, which must be distributed under the terms of Sections
|
||||||
|
1 and 2 above on a medium customarily used for software interchange; or,
|
||||||
|
|
||||||
|
b) Accompany it with a written offer, valid for at least three
|
||||||
|
years, to give any third party, for a charge no more than your
|
||||||
|
cost of physically performing source distribution, a complete
|
||||||
|
machine-readable copy of the corresponding source code, to be
|
||||||
|
distributed under the terms of Sections 1 and 2 above on a medium
|
||||||
|
customarily used for software interchange; or,
|
||||||
|
|
||||||
|
c) Accompany it with the information you received as to the offer
|
||||||
|
to distribute corresponding source code. (This alternative is
|
||||||
|
allowed only for noncommercial distribution and only if you
|
||||||
|
received the program in object code or executable form with such
|
||||||
|
an offer, in accord with Subsection b above.)
|
||||||
|
|
||||||
|
The source code for a work means the preferred form of the work for
|
||||||
|
making modifications to it. For an executable work, complete source
|
||||||
|
code means all the source code for all modules it contains, plus any
|
||||||
|
associated interface definition files, plus the scripts used to
|
||||||
|
control compilation and installation of the executable. However, as a
|
||||||
|
special exception, the source code distributed need not include
|
||||||
|
anything that is normally distributed (in either source or binary
|
||||||
|
form) with the major components (compiler, kernel, and so on) of the
|
||||||
|
operating system on which the executable runs, unless that component
|
||||||
|
itself accompanies the executable.
|
||||||
|
|
||||||
|
If distribution of executable or object code is made by offering
|
||||||
|
access to copy from a designated place, then offering equivalent
|
||||||
|
access to copy the source code from the same place counts as
|
||||||
|
distribution of the source code, even though third parties are not
|
||||||
|
compelled to copy the source along with the object code.
|
||||||
|
|
||||||
|
4. You may not copy, modify, sublicense, or distribute the Program
|
||||||
|
except as expressly provided under this License. Any attempt
|
||||||
|
otherwise to copy, modify, sublicense or distribute the Program is
|
||||||
|
void, and will automatically terminate your rights under this License.
|
||||||
|
However, parties who have received copies, or rights, from you under
|
||||||
|
this License will not have their licenses terminated so long as such
|
||||||
|
parties remain in full compliance.
|
||||||
|
|
||||||
|
5. You are not required to accept this License, since you have not
|
||||||
|
signed it. However, nothing else grants you permission to modify or
|
||||||
|
distribute the Program or its derivative works. These actions are
|
||||||
|
prohibited by law if you do not accept this License. Therefore, by
|
||||||
|
modifying or distributing the Program (or any work based on the
|
||||||
|
Program), you indicate your acceptance of this License to do so, and
|
||||||
|
all its terms and conditions for copying, distributing or modifying
|
||||||
|
the Program or works based on it.
|
||||||
|
|
||||||
|
6. Each time you redistribute the Program (or any work based on the
|
||||||
|
Program), the recipient automatically receives a license from the
|
||||||
|
original licensor to copy, distribute or modify the Program subject to
|
||||||
|
these terms and conditions. You may not impose any further
|
||||||
|
restrictions on the recipients' exercise of the rights granted herein.
|
||||||
|
You are not responsible for enforcing compliance by third parties to
|
||||||
|
this License.
|
||||||
|
|
||||||
|
7. If, as a consequence of a court judgment or allegation of patent
|
||||||
|
infringement or for any other reason (not limited to patent issues),
|
||||||
|
conditions are imposed on you (whether by court order, agreement or
|
||||||
|
otherwise) that contradict the conditions of this License, they do not
|
||||||
|
excuse you from the conditions of this License. If you cannot
|
||||||
|
distribute so as to satisfy simultaneously your obligations under this
|
||||||
|
License and any other pertinent obligations, then as a consequence you
|
||||||
|
may not distribute the Program at all. For example, if a patent
|
||||||
|
license would not permit royalty-free redistribution of the Program by
|
||||||
|
all those who receive copies directly or indirectly through you, then
|
||||||
|
the only way you could satisfy both it and this License would be to
|
||||||
|
refrain entirely from distribution of the Program.
|
||||||
|
|
||||||
|
If any portion of this section is held invalid or unenforceable under
|
||||||
|
any particular circumstance, the balance of the section is intended to
|
||||||
|
apply and the section as a whole is intended to apply in other
|
||||||
|
circumstances.
|
||||||
|
|
||||||
|
It is not the purpose of this section to induce you to infringe any
|
||||||
|
patents or other property right claims or to contest validity of any
|
||||||
|
such claims; this section has the sole purpose of protecting the
|
||||||
|
integrity of the free software distribution system, which is
|
||||||
|
implemented by public license practices. Many people have made
|
||||||
|
generous contributions to the wide range of software distributed
|
||||||
|
through that system in reliance on consistent application of that
|
||||||
|
system; it is up to the author/donor to decide if he or she is willing
|
||||||
|
to distribute software through any other system and a licensee cannot
|
||||||
|
impose that choice.
|
||||||
|
|
||||||
|
This section is intended to make thoroughly clear what is believed to
|
||||||
|
be a consequence of the rest of this License.
|
||||||
|
|
||||||
|
8. If the distribution and/or use of the Program is restricted in
|
||||||
|
certain countries either by patents or by copyrighted interfaces, the
|
||||||
|
original copyright holder who places the Program under this License
|
||||||
|
may add an explicit geographical distribution limitation excluding
|
||||||
|
those countries, so that distribution is permitted only in or among
|
||||||
|
countries not thus excluded. In such case, this License incorporates
|
||||||
|
the limitation as if written in the body of this License.
|
||||||
|
|
||||||
|
9. The Free Software Foundation may publish revised and/or new versions
|
||||||
|
of the General Public License from time to time. Such new versions will
|
||||||
|
be similar in spirit to the present version, but may differ in detail to
|
||||||
|
address new problems or concerns.
|
||||||
|
|
||||||
|
Each version is given a distinguishing version number. If the Program
|
||||||
|
specifies a version number of this License which applies to it and "any
|
||||||
|
later version", you have the option of following the terms and conditions
|
||||||
|
either of that version or of any later version published by the Free
|
||||||
|
Software Foundation. If the Program does not specify a version number of
|
||||||
|
this License, you may choose any version ever published by the Free Software
|
||||||
|
Foundation.
|
||||||
|
|
||||||
|
10. If you wish to incorporate parts of the Program into other free
|
||||||
|
programs whose distribution conditions are different, write to the author
|
||||||
|
to ask for permission. For software which is copyrighted by the Free
|
||||||
|
Software Foundation, write to the Free Software Foundation; we sometimes
|
||||||
|
make exceptions for this. Our decision will be guided by the two goals
|
||||||
|
of preserving the free status of all derivatives of our free software and
|
||||||
|
of promoting the sharing and reuse of software generally.
|
||||||
|
|
||||||
|
NO WARRANTY
|
||||||
|
|
||||||
|
11. BECAUSE THE PROGRAM IS LICENSED FREE OF CHARGE, THERE IS NO WARRANTY
|
||||||
|
FOR THE PROGRAM, TO THE EXTENT PERMITTED BY APPLICABLE LAW. EXCEPT WHEN
|
||||||
|
OTHERWISE STATED IN WRITING THE COPYRIGHT HOLDERS AND/OR OTHER PARTIES
|
||||||
|
PROVIDE THE PROGRAM "AS IS" WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED
|
||||||
|
OR IMPLIED, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
|
||||||
|
MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. THE ENTIRE RISK AS
|
||||||
|
TO THE QUALITY AND PERFORMANCE OF THE PROGRAM IS WITH YOU. SHOULD THE
|
||||||
|
PROGRAM PROVE DEFECTIVE, YOU ASSUME THE COST OF ALL NECESSARY SERVICING,
|
||||||
|
REPAIR OR CORRECTION.
|
||||||
|
|
||||||
|
12. IN NO EVENT UNLESS REQUIRED BY APPLICABLE LAW OR AGREED TO IN WRITING
|
||||||
|
WILL ANY COPYRIGHT HOLDER, OR ANY OTHER PARTY WHO MAY MODIFY AND/OR
|
||||||
|
REDISTRIBUTE THE PROGRAM AS PERMITTED ABOVE, BE LIABLE TO YOU FOR DAMAGES,
|
||||||
|
INCLUDING ANY GENERAL, SPECIAL, INCIDENTAL OR CONSEQUENTIAL DAMAGES ARISING
|
||||||
|
OUT OF THE USE OR INABILITY TO USE THE PROGRAM (INCLUDING BUT NOT LIMITED
|
||||||
|
TO LOSS OF DATA OR DATA BEING RENDERED INACCURATE OR LOSSES SUSTAINED BY
|
||||||
|
YOU OR THIRD PARTIES OR A FAILURE OF THE PROGRAM TO OPERATE WITH ANY OTHER
|
||||||
|
PROGRAMS), EVEN IF SUCH HOLDER OR OTHER PARTY HAS BEEN ADVISED OF THE
|
||||||
|
POSSIBILITY OF SUCH DAMAGES.
|
||||||
|
|
||||||
|
END OF TERMS AND CONDITIONS
|
||||||
|
|
||||||
|
How to Apply These Terms to Your New Programs
|
||||||
|
|
||||||
|
If you develop a new program, and you want it to be of the greatest
|
||||||
|
possible use to the public, the best way to achieve this is to make it
|
||||||
|
free software which everyone can redistribute and change under these terms.
|
||||||
|
|
||||||
|
To do so, attach the following notices to the program. It is safest
|
||||||
|
to attach them to the start of each source file to most effectively
|
||||||
|
convey the exclusion of warranty; and each file should have at least
|
||||||
|
the "copyright" line and a pointer to where the full notice is found.
|
||||||
|
|
||||||
|
<one line to give the program's name and a brief idea of what it does.>
|
||||||
|
Copyright (C) <year> <name of author>
|
||||||
|
|
||||||
|
This program is free software; you can redistribute it and/or modify
|
||||||
|
it under the terms of the GNU General Public License as published by
|
||||||
|
the Free Software Foundation; either version 2 of the License, or
|
||||||
|
(at your option) any later version.
|
||||||
|
|
||||||
|
This program is distributed in the hope that it will be useful,
|
||||||
|
but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
GNU General Public License for more details.
|
||||||
|
|
||||||
|
You should have received a copy of the GNU General Public License along
|
||||||
|
with this program; if not, write to the Free Software Foundation, Inc.,
|
||||||
|
51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
|
||||||
|
|
||||||
|
Also add information on how to contact you by electronic and paper mail.
|
||||||
|
|
||||||
|
If the program is interactive, make it output a short notice like this
|
||||||
|
when it starts in an interactive mode:
|
||||||
|
|
||||||
|
Gnomovision version 69, Copyright (C) year name of author
|
||||||
|
Gnomovision comes with ABSOLUTELY NO WARRANTY; for details type `show w'.
|
||||||
|
This is free software, and you are welcome to redistribute it
|
||||||
|
under certain conditions; type `show c' for details.
|
||||||
|
|
||||||
|
The hypothetical commands `show w' and `show c' should show the appropriate
|
||||||
|
parts of the General Public License. Of course, the commands you use may
|
||||||
|
be called something other than `show w' and `show c'; they could even be
|
||||||
|
mouse-clicks or menu items--whatever suits your program.
|
||||||
|
|
||||||
|
You should also get your employer (if you work as a programmer) or your
|
||||||
|
school, if any, to sign a "copyright disclaimer" for the program, if
|
||||||
|
necessary. Here is a sample; alter the names:
|
||||||
|
|
||||||
|
Yoyodyne, Inc., hereby disclaims all copyright interest in the program
|
||||||
|
`Gnomovision' (which makes passes at compilers) written by James Hacker.
|
||||||
|
|
||||||
|
<signature of Ty Coon>, 1 April 1989
|
||||||
|
Ty Coon, President of Vice
|
||||||
|
|
||||||
|
This General Public License does not permit incorporating your program into
|
||||||
|
proprietary programs. If your program is a subroutine library, you may
|
||||||
|
consider it more useful to permit linking proprietary applications with the
|
||||||
|
library. If this is what you want to do, use the GNU Lesser General
|
||||||
|
Public License instead of this License.
|
27
README
Normal file
27
README
Normal file
@ -0,0 +1,27 @@
|
|||||||
|
Signing kernel modules and EFI binaries in the Open Build Service
|
||||||
|
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||||
|
|
||||||
|
Note: Not everything that is described here is actually implemented. Even
|
||||||
|
those parts that are implemented can change slightly.
|
||||||
|
|
||||||
|
Packages that need to sign files during build should add the following lines
|
||||||
|
to the specfile
|
||||||
|
|
||||||
|
# needssslcertforbuild
|
||||||
|
%define sign_files pattern...
|
||||||
|
BuildRequires: pesign-obs-integration
|
||||||
|
|
||||||
|
The "# needssslcertforbuild" comment tells the buildservice to store the
|
||||||
|
signing certificate in %_sourcedir/_projectcert.crt. At the end of the
|
||||||
|
install phase, the pesign-install-post script computes hashes of all
|
||||||
|
files matching the patterns in %sign_files. The sha256 hashes are stored
|
||||||
|
in %_topdir/OTHER/%name.cpio.rsasign, plus the script places a
|
||||||
|
pesign-repackage.spec file there. When the first rpmbuild finishes, the
|
||||||
|
buildservice sends the cpio archive to the signing server, which returns
|
||||||
|
a rsasigned.cio archive with RSA signatures of the sha256 hashes.
|
||||||
|
|
||||||
|
The pesign-repackage.spec takes the original RPMs, unpacks them and
|
||||||
|
appends the signatures to the files (TODO: only implemented for firmware
|
||||||
|
files). It then uses the pesign-gen-repackage-spec script to generate
|
||||||
|
another specfile, which builds new RPMs with signed files.
|
||||||
|
|
441
kernel-sign-file
Normal file
441
kernel-sign-file
Normal file
@ -0,0 +1,441 @@
|
|||||||
|
#!/usr/bin/perl -w
|
||||||
|
#
|
||||||
|
# Sign a module file using the given key.
|
||||||
|
#
|
||||||
|
|
||||||
|
my $USAGE =
|
||||||
|
"Usage: scripts/sign-file [-v] [-f] <hash algo> <key> <x509> <module> [<dest>]\n" .
|
||||||
|
" scripts/sign-file [-v] [-f] -s <raw sig> <hash algo> <x509> <module> [<dest>]\n" .
|
||||||
|
" -v verbose output\n" .
|
||||||
|
" -f create a firmware signature file\n";
|
||||||
|
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
use FileHandle;
|
||||||
|
use IPC::Open2;
|
||||||
|
use Getopt::Std;
|
||||||
|
|
||||||
|
my %opts;
|
||||||
|
getopts('vfs:', \%opts) or die $USAGE;
|
||||||
|
my $verbose = $opts{'v'};
|
||||||
|
my $signature_file = $opts{'s'};
|
||||||
|
my $sign_fw = $opts{'f'};
|
||||||
|
|
||||||
|
die $USAGE if ($#ARGV > 4);
|
||||||
|
die $USAGE if (!$signature_file && $#ARGV < 3 || $signature_file && $#ARGV < 2);
|
||||||
|
|
||||||
|
my $dgst = shift @ARGV;
|
||||||
|
my $private_key;
|
||||||
|
if (!$signature_file) {
|
||||||
|
$private_key = shift @ARGV;
|
||||||
|
}
|
||||||
|
my $x509 = shift @ARGV;
|
||||||
|
my $module = shift @ARGV;
|
||||||
|
my ($dest, $keep_orig);
|
||||||
|
if (@ARGV) {
|
||||||
|
$dest = $ARGV[0];
|
||||||
|
$keep_orig = 1;
|
||||||
|
} elsif ($sign_fw) {
|
||||||
|
$dest = $module . ".sig";
|
||||||
|
$keep_orig = 1;
|
||||||
|
} else {
|
||||||
|
$dest = $module . "~";
|
||||||
|
}
|
||||||
|
my $mode_name = $sign_fw ? "firmware" : "module";
|
||||||
|
|
||||||
|
die "Can't read private key\n" if (!$signature_file && !-r $private_key);
|
||||||
|
die "Can't read signature file\n" if ($signature_file && !-r $signature_file);
|
||||||
|
die "Can't read X.509 certificate\n" unless (-r $x509);
|
||||||
|
die "Can't read $mode_name\n" unless (-r $module);
|
||||||
|
|
||||||
|
#
|
||||||
|
# Function to read the contents of a file into a variable.
|
||||||
|
#
|
||||||
|
sub read_file($)
|
||||||
|
{
|
||||||
|
my ($file) = @_;
|
||||||
|
my $contents;
|
||||||
|
my $len;
|
||||||
|
|
||||||
|
open(FD, "<$file") || die $file;
|
||||||
|
binmode FD;
|
||||||
|
my @st = stat(FD);
|
||||||
|
die $file if (!@st);
|
||||||
|
$len = read(FD, $contents, $st[7]) || die $file;
|
||||||
|
close(FD) || die $file;
|
||||||
|
die "$file: Wanted length ", $st[7], ", got ", $len, "\n"
|
||||||
|
if ($len != $st[7]);
|
||||||
|
return $contents;
|
||||||
|
}
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
#
|
||||||
|
# First of all, we have to parse the X.509 certificate to find certain details
|
||||||
|
# about it.
|
||||||
|
#
|
||||||
|
# We read the DER-encoded X509 certificate and parse it to extract the Subject
|
||||||
|
# name and Subject Key Identifier. Theis provides the data we need to build
|
||||||
|
# the certificate identifier.
|
||||||
|
#
|
||||||
|
# The signer's name part of the identifier is fabricated from the commonName,
|
||||||
|
# the organizationName or the emailAddress components of the X.509 subject
|
||||||
|
# name.
|
||||||
|
#
|
||||||
|
# The subject key ID is used to select which of that signer's certificates
|
||||||
|
# we're intending to use to sign the module.
|
||||||
|
#
|
||||||
|
###############################################################################
|
||||||
|
my $x509_certificate = read_file($x509);
|
||||||
|
|
||||||
|
my $UNIV = 0 << 6;
|
||||||
|
my $APPL = 1 << 6;
|
||||||
|
my $CONT = 2 << 6;
|
||||||
|
my $PRIV = 3 << 6;
|
||||||
|
|
||||||
|
my $CONS = 0x20;
|
||||||
|
|
||||||
|
my $BOOLEAN = 0x01;
|
||||||
|
my $INTEGER = 0x02;
|
||||||
|
my $BIT_STRING = 0x03;
|
||||||
|
my $OCTET_STRING = 0x04;
|
||||||
|
my $NULL = 0x05;
|
||||||
|
my $OBJ_ID = 0x06;
|
||||||
|
my $UTF8String = 0x0c;
|
||||||
|
my $SEQUENCE = 0x10;
|
||||||
|
my $SET = 0x11;
|
||||||
|
my $UTCTime = 0x17;
|
||||||
|
my $GeneralizedTime = 0x18;
|
||||||
|
|
||||||
|
my %OIDs = (
|
||||||
|
pack("CCC", 85, 4, 3) => "commonName",
|
||||||
|
pack("CCC", 85, 4, 6) => "countryName",
|
||||||
|
pack("CCC", 85, 4, 10) => "organizationName",
|
||||||
|
pack("CCC", 85, 4, 11) => "organizationUnitName",
|
||||||
|
pack("CCCCCCCCC", 42, 134, 72, 134, 247, 13, 1, 1, 1) => "rsaEncryption",
|
||||||
|
pack("CCCCCCCCC", 42, 134, 72, 134, 247, 13, 1, 1, 5) => "sha1WithRSAEncryption",
|
||||||
|
pack("CCCCCCCCC", 42, 134, 72, 134, 247, 13, 1, 9, 1) => "emailAddress",
|
||||||
|
pack("CCC", 85, 29, 35) => "authorityKeyIdentifier",
|
||||||
|
pack("CCC", 85, 29, 14) => "subjectKeyIdentifier",
|
||||||
|
pack("CCC", 85, 29, 19) => "basicConstraints"
|
||||||
|
);
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
#
|
||||||
|
# Extract an ASN.1 element from a string and return information about it.
|
||||||
|
#
|
||||||
|
###############################################################################
|
||||||
|
sub asn1_extract($$@)
|
||||||
|
{
|
||||||
|
my ($cursor, $expected_tag, $optional) = @_;
|
||||||
|
|
||||||
|
return [ -1 ]
|
||||||
|
if ($cursor->[1] == 0 && $optional);
|
||||||
|
|
||||||
|
die $x509, ": ", $cursor->[0], ": ASN.1 data underrun (elem ", $cursor->[1], ")\n"
|
||||||
|
if ($cursor->[1] < 2);
|
||||||
|
|
||||||
|
my ($tag, $len) = unpack("CC", substr(${$cursor->[2]}, $cursor->[0], 2));
|
||||||
|
|
||||||
|
if ($expected_tag != -1 && $tag != $expected_tag) {
|
||||||
|
return [ -1 ]
|
||||||
|
if ($optional);
|
||||||
|
die $x509, ": ", $cursor->[0], ": ASN.1 unexpected tag (", $tag,
|
||||||
|
" not ", $expected_tag, ")\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
$cursor->[0] += 2;
|
||||||
|
$cursor->[1] -= 2;
|
||||||
|
|
||||||
|
die $x509, ": ", $cursor->[0], ": ASN.1 long tag\n"
|
||||||
|
if (($tag & 0x1f) == 0x1f);
|
||||||
|
die $x509, ": ", $cursor->[0], ": ASN.1 indefinite length\n"
|
||||||
|
if ($len == 0x80);
|
||||||
|
|
||||||
|
if ($len > 0x80) {
|
||||||
|
my $l = $len - 0x80;
|
||||||
|
die $x509, ": ", $cursor->[0], ": ASN.1 data underrun (len len $l)\n"
|
||||||
|
if ($cursor->[1] < $l);
|
||||||
|
|
||||||
|
if ($l == 0x1) {
|
||||||
|
$len = unpack("C", substr(${$cursor->[2]}, $cursor->[0], 1));
|
||||||
|
} elsif ($l == 0x2) {
|
||||||
|
$len = unpack("n", substr(${$cursor->[2]}, $cursor->[0], 2));
|
||||||
|
} elsif ($l == 0x3) {
|
||||||
|
$len = unpack("C", substr(${$cursor->[2]}, $cursor->[0], 1)) << 16;
|
||||||
|
$len = unpack("n", substr(${$cursor->[2]}, $cursor->[0] + 1, 2));
|
||||||
|
} elsif ($l == 0x4) {
|
||||||
|
$len = unpack("N", substr(${$cursor->[2]}, $cursor->[0], 4));
|
||||||
|
} else {
|
||||||
|
die $x509, ": ", $cursor->[0], ": ASN.1 element too long (", $l, ")\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
$cursor->[0] += $l;
|
||||||
|
$cursor->[1] -= $l;
|
||||||
|
}
|
||||||
|
|
||||||
|
die $x509, ": ", $cursor->[0], ": ASN.1 data underrun (", $len, ")\n"
|
||||||
|
if ($cursor->[1] < $len);
|
||||||
|
|
||||||
|
my $ret = [ $tag, [ $cursor->[0], $len, $cursor->[2] ] ];
|
||||||
|
$cursor->[0] += $len;
|
||||||
|
$cursor->[1] -= $len;
|
||||||
|
|
||||||
|
return $ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
#
|
||||||
|
# Retrieve the data referred to by a cursor
|
||||||
|
#
|
||||||
|
###############################################################################
|
||||||
|
sub asn1_retrieve($)
|
||||||
|
{
|
||||||
|
my ($cursor) = @_;
|
||||||
|
my ($offset, $len, $data) = @$cursor;
|
||||||
|
return substr($$data, $offset, $len);
|
||||||
|
}
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
#
|
||||||
|
# Roughly parse the X.509 certificate
|
||||||
|
#
|
||||||
|
###############################################################################
|
||||||
|
my $cursor = [ 0, length($x509_certificate), \$x509_certificate ];
|
||||||
|
|
||||||
|
my $cert = asn1_extract($cursor, $UNIV | $CONS | $SEQUENCE);
|
||||||
|
my $tbs = asn1_extract($cert->[1], $UNIV | $CONS | $SEQUENCE);
|
||||||
|
my $version = asn1_extract($tbs->[1], $CONT | $CONS | 0, 1);
|
||||||
|
my $serial_number = asn1_extract($tbs->[1], $UNIV | $INTEGER);
|
||||||
|
my $sig_type = asn1_extract($tbs->[1], $UNIV | $CONS | $SEQUENCE);
|
||||||
|
my $issuer = asn1_extract($tbs->[1], $UNIV | $CONS | $SEQUENCE);
|
||||||
|
my $validity = asn1_extract($tbs->[1], $UNIV | $CONS | $SEQUENCE);
|
||||||
|
my $subject = asn1_extract($tbs->[1], $UNIV | $CONS | $SEQUENCE);
|
||||||
|
my $key = asn1_extract($tbs->[1], $UNIV | $CONS | $SEQUENCE);
|
||||||
|
my $issuer_uid = asn1_extract($tbs->[1], $CONT | $CONS | 1, 1);
|
||||||
|
my $subject_uid = asn1_extract($tbs->[1], $CONT | $CONS | 2, 1);
|
||||||
|
my $extension_list = asn1_extract($tbs->[1], $CONT | $CONS | 3, 1);
|
||||||
|
|
||||||
|
my $subject_key_id = ();
|
||||||
|
my $authority_key_id = ();
|
||||||
|
|
||||||
|
#
|
||||||
|
# Parse the extension list
|
||||||
|
#
|
||||||
|
if ($extension_list->[0] != -1) {
|
||||||
|
my $extensions = asn1_extract($extension_list->[1], $UNIV | $CONS | $SEQUENCE);
|
||||||
|
|
||||||
|
while ($extensions->[1]->[1] > 0) {
|
||||||
|
my $ext = asn1_extract($extensions->[1], $UNIV | $CONS | $SEQUENCE);
|
||||||
|
my $x_oid = asn1_extract($ext->[1], $UNIV | $OBJ_ID);
|
||||||
|
my $x_crit = asn1_extract($ext->[1], $UNIV | $BOOLEAN, 1);
|
||||||
|
my $x_val = asn1_extract($ext->[1], $UNIV | $OCTET_STRING);
|
||||||
|
|
||||||
|
my $raw_oid = asn1_retrieve($x_oid->[1]);
|
||||||
|
next if (!exists($OIDs{$raw_oid}));
|
||||||
|
my $x_type = $OIDs{$raw_oid};
|
||||||
|
|
||||||
|
my $raw_value = asn1_retrieve($x_val->[1]);
|
||||||
|
|
||||||
|
if ($x_type eq "subjectKeyIdentifier") {
|
||||||
|
my $vcursor = [ 0, length($raw_value), \$raw_value ];
|
||||||
|
|
||||||
|
$subject_key_id = asn1_extract($vcursor, $UNIV | $OCTET_STRING);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
#
|
||||||
|
# Determine what we're going to use as the signer's name. In order of
|
||||||
|
# preference, take one of: commonName, organizationName or emailAddress.
|
||||||
|
#
|
||||||
|
###############################################################################
|
||||||
|
my $org = "";
|
||||||
|
my $cn = "";
|
||||||
|
my $email = "";
|
||||||
|
|
||||||
|
while ($subject->[1]->[1] > 0) {
|
||||||
|
my $rdn = asn1_extract($subject->[1], $UNIV | $CONS | $SET);
|
||||||
|
my $attr = asn1_extract($rdn->[1], $UNIV | $CONS | $SEQUENCE);
|
||||||
|
my $n_oid = asn1_extract($attr->[1], $UNIV | $OBJ_ID);
|
||||||
|
my $n_val = asn1_extract($attr->[1], -1);
|
||||||
|
|
||||||
|
my $raw_oid = asn1_retrieve($n_oid->[1]);
|
||||||
|
next if (!exists($OIDs{$raw_oid}));
|
||||||
|
my $n_type = $OIDs{$raw_oid};
|
||||||
|
|
||||||
|
my $raw_value = asn1_retrieve($n_val->[1]);
|
||||||
|
|
||||||
|
if ($n_type eq "organizationName") {
|
||||||
|
$org = $raw_value;
|
||||||
|
} elsif ($n_type eq "commonName") {
|
||||||
|
$cn = $raw_value;
|
||||||
|
} elsif ($n_type eq "emailAddress") {
|
||||||
|
$email = $raw_value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
my $signers_name = $email;
|
||||||
|
|
||||||
|
if ($org && $cn) {
|
||||||
|
# Don't use the organizationName if the commonName repeats it
|
||||||
|
if (length($org) <= length($cn) &&
|
||||||
|
substr($cn, 0, length($org)) eq $org) {
|
||||||
|
$signers_name = $cn;
|
||||||
|
goto got_id_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
# Or a signifcant chunk of it
|
||||||
|
if (length($org) >= 7 &&
|
||||||
|
length($cn) >= 7 &&
|
||||||
|
substr($cn, 0, 7) eq substr($org, 0, 7)) {
|
||||||
|
$signers_name = $cn;
|
||||||
|
goto got_id_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
$signers_name = $org . ": " . $cn;
|
||||||
|
} elsif ($org) {
|
||||||
|
$signers_name = $org;
|
||||||
|
} elsif ($cn) {
|
||||||
|
$signers_name = $cn;
|
||||||
|
}
|
||||||
|
|
||||||
|
got_id_name:
|
||||||
|
|
||||||
|
die $x509, ": ", "X.509: Couldn't find the Subject Key Identifier extension\n"
|
||||||
|
if (!$subject_key_id);
|
||||||
|
|
||||||
|
my $key_identifier = asn1_retrieve($subject_key_id->[1]);
|
||||||
|
|
||||||
|
###############################################################################
|
||||||
|
#
|
||||||
|
# Create and attach the module signature
|
||||||
|
#
|
||||||
|
###############################################################################
|
||||||
|
|
||||||
|
#
|
||||||
|
# Signature parameters
|
||||||
|
#
|
||||||
|
my $algo = 1; # Public-key crypto algorithm: RSA
|
||||||
|
my $hash = 0; # Digest algorithm
|
||||||
|
my $id_type = 1; # Identifier type: X.509
|
||||||
|
|
||||||
|
#
|
||||||
|
# Digest the data
|
||||||
|
#
|
||||||
|
my $prologue;
|
||||||
|
if ($dgst eq "sha1") {
|
||||||
|
$prologue = pack("C*",
|
||||||
|
0x30, 0x21, 0x30, 0x09, 0x06, 0x05,
|
||||||
|
0x2B, 0x0E, 0x03, 0x02, 0x1A,
|
||||||
|
0x05, 0x00, 0x04, 0x14);
|
||||||
|
$hash = 2;
|
||||||
|
} elsif ($dgst eq "sha224") {
|
||||||
|
$prologue = pack("C*",
|
||||||
|
0x30, 0x2d, 0x30, 0x0d, 0x06, 0x09,
|
||||||
|
0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x04,
|
||||||
|
0x05, 0x00, 0x04, 0x1C);
|
||||||
|
$hash = 7;
|
||||||
|
} elsif ($dgst eq "sha256") {
|
||||||
|
$prologue = pack("C*",
|
||||||
|
0x30, 0x31, 0x30, 0x0d, 0x06, 0x09,
|
||||||
|
0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x01,
|
||||||
|
0x05, 0x00, 0x04, 0x20);
|
||||||
|
$hash = 4;
|
||||||
|
} elsif ($dgst eq "sha384") {
|
||||||
|
$prologue = pack("C*",
|
||||||
|
0x30, 0x41, 0x30, 0x0d, 0x06, 0x09,
|
||||||
|
0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x02,
|
||||||
|
0x05, 0x00, 0x04, 0x30);
|
||||||
|
$hash = 5;
|
||||||
|
} elsif ($dgst eq "sha512") {
|
||||||
|
$prologue = pack("C*",
|
||||||
|
0x30, 0x51, 0x30, 0x0d, 0x06, 0x09,
|
||||||
|
0x60, 0x86, 0x48, 0x01, 0x65, 0x03, 0x04, 0x02, 0x03,
|
||||||
|
0x05, 0x00, 0x04, 0x40);
|
||||||
|
$hash = 6;
|
||||||
|
} else {
|
||||||
|
die "Unknown hash algorithm: $dgst\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
my $signature;
|
||||||
|
if ($signature_file) {
|
||||||
|
$signature = read_file($signature_file);
|
||||||
|
} else {
|
||||||
|
#
|
||||||
|
# Generate the digest and read from openssl's stdout
|
||||||
|
#
|
||||||
|
my $digest;
|
||||||
|
$digest = readpipe("openssl dgst -$dgst -binary $module") || die "openssl dgst";
|
||||||
|
|
||||||
|
#
|
||||||
|
# Generate the binary signature, which will be just the integer that
|
||||||
|
# comprises the signature with no metadata attached.
|
||||||
|
#
|
||||||
|
my $pid;
|
||||||
|
$pid = open2(*read_from, *write_to,
|
||||||
|
"openssl rsautl -sign -inkey $private_key -keyform PEM") ||
|
||||||
|
die "openssl rsautl";
|
||||||
|
binmode write_to;
|
||||||
|
print write_to $prologue . $digest || die "pipe to openssl rsautl";
|
||||||
|
close(write_to) || die "pipe to openssl rsautl";
|
||||||
|
|
||||||
|
binmode read_from;
|
||||||
|
read(read_from, $signature, 4096) || die "pipe from openssl rsautl";
|
||||||
|
close(read_from) || die "pipe from openssl rsautl";
|
||||||
|
waitpid($pid, 0) || die;
|
||||||
|
die "openssl rsautl died: $?" if ($? >> 8);
|
||||||
|
}
|
||||||
|
$signature = pack("n", length($signature)) . $signature,
|
||||||
|
|
||||||
|
#
|
||||||
|
# Build the signed binary
|
||||||
|
#
|
||||||
|
my $unsigned_module = read_file($module);
|
||||||
|
|
||||||
|
my $magic_number = $sign_fw ?
|
||||||
|
"~Linux firmware signature~\n" :
|
||||||
|
"~Module signature appended~\n";
|
||||||
|
|
||||||
|
my $info = pack("CCCCCxxxN",
|
||||||
|
$algo, $hash, $id_type,
|
||||||
|
length($signers_name),
|
||||||
|
length($key_identifier),
|
||||||
|
length($signature));
|
||||||
|
|
||||||
|
if ($verbose) {
|
||||||
|
print "Size of unsigned $mode_name: ", length($unsigned_module), "\n";
|
||||||
|
print "Size of signer's name : ", length($signers_name), "\n";
|
||||||
|
print "Size of key identifier : ", length($key_identifier), "\n";
|
||||||
|
print "Size of signature : ", length($signature), "\n";
|
||||||
|
print "Size of informaton : ", length($info), "\n";
|
||||||
|
print "Size of magic number : ", length($magic_number), "\n";
|
||||||
|
print "Signer's name : '", $signers_name, "'\n";
|
||||||
|
print "Digest : $dgst\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
open(FD, ">$dest") || die $dest;
|
||||||
|
binmode FD;
|
||||||
|
if ($sign_fw) {
|
||||||
|
print FD
|
||||||
|
$magic_number,
|
||||||
|
$info,
|
||||||
|
$signers_name,
|
||||||
|
$key_identifier,
|
||||||
|
$signature
|
||||||
|
;
|
||||||
|
} else {
|
||||||
|
print FD
|
||||||
|
$unsigned_module,
|
||||||
|
$signers_name,
|
||||||
|
$key_identifier,
|
||||||
|
$signature,
|
||||||
|
$info,
|
||||||
|
$magic_number
|
||||||
|
;
|
||||||
|
}
|
||||||
|
close FD || die $dest;
|
||||||
|
|
||||||
|
if (!$keep_orig) {
|
||||||
|
rename($dest, $module) || die $module;
|
||||||
|
}
|
5
macros.pesign-obs
Normal file
5
macros.pesign-obs
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
# Macros for pesign / modsign OBS integration
|
||||||
|
|
||||||
|
# The spec file should define %sign_files to a space-separated list of patterns
|
||||||
|
# of files to be signed, e.g. %define sign_files /lib/firmware *.ko
|
||||||
|
%__os_install_post /usr/lib/rpm/pesign-install-post --files "%{?sign_files}" --output %_topdir/OTHER
|
369
pesign-gen-repackage-spec
Normal file
369
pesign-gen-repackage-spec
Normal file
@ -0,0 +1,369 @@
|
|||||||
|
#!/usr/bin/perl
|
||||||
|
# Given a set of rpm packages and directory with their new content,
|
||||||
|
# generate a specfile that generates new packages
|
||||||
|
#
|
||||||
|
# Copyright (c) 2013 SUSE Linux Products GmbH, Nuernberg, Germany.
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
|
|
||||||
|
use strict;
|
||||||
|
use warnings;
|
||||||
|
|
||||||
|
my $USAGE = "Usage: $0 --directory <payload directory> rpm...\n";
|
||||||
|
|
||||||
|
use Getopt::Long;
|
||||||
|
use Fcntl qw(:mode :seek);
|
||||||
|
|
||||||
|
my $directory;
|
||||||
|
my $output = ".";
|
||||||
|
my @rpms;
|
||||||
|
|
||||||
|
$ENV{LC_ALL} = "en_US.UTF-8";
|
||||||
|
|
||||||
|
GetOptions(
|
||||||
|
"help|h" => sub { print $USAGE; exit; },
|
||||||
|
"directory|d=s" => \$directory,
|
||||||
|
"output|o=s" => \$output,
|
||||||
|
) or die $USAGE;
|
||||||
|
@rpms = @ARGV;
|
||||||
|
if (!@rpms) {
|
||||||
|
print STDERR "$0: No packages given\n";
|
||||||
|
die $USAGE;
|
||||||
|
}
|
||||||
|
if (!$directory || substr($directory, 0, 1) ne '/' || ! -d $directory) {
|
||||||
|
print STDERR "$0: --directory must be an absolute path\n";
|
||||||
|
die $USAGE;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub query_array {
|
||||||
|
my ($rpm, @tags) = @_;
|
||||||
|
my @res;
|
||||||
|
|
||||||
|
my $format = "[" . join("|", map { "\%{$_}" } @tags) . "\\n]";
|
||||||
|
open(my $fh, '-|', "rpm", "-qp", "--qf", $format, $rpm)
|
||||||
|
or die "rpm: $!\n";
|
||||||
|
while (<$fh>) {
|
||||||
|
chomp;
|
||||||
|
my @t = split(/\|/, $_, -1);
|
||||||
|
push(@res, \@t);
|
||||||
|
}
|
||||||
|
close($fh);
|
||||||
|
return @res;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub query_single {
|
||||||
|
my ($rpm, $tag) = @_;
|
||||||
|
my $res;
|
||||||
|
|
||||||
|
open(my $fh, '-|', "rpm", "-qp", "--qf", "\%{$tag}\\n", $rpm)
|
||||||
|
or die "rpm: $!\n";
|
||||||
|
{
|
||||||
|
local $/ = undef;
|
||||||
|
$res = <$fh>;
|
||||||
|
}
|
||||||
|
chomp $res;
|
||||||
|
close($fh);
|
||||||
|
return $res;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
# specfile dependency => rpm tag name
|
||||||
|
my %dep2tag = (
|
||||||
|
conflicts => "conflict",
|
||||||
|
obsoletes => "obsolete",
|
||||||
|
provides => "provide",
|
||||||
|
requires => "require",
|
||||||
|
suggests => "suggests",
|
||||||
|
enhances => "enhances",
|
||||||
|
);
|
||||||
|
|
||||||
|
# strong version of suggests and enhances
|
||||||
|
my %dep2strong = (
|
||||||
|
suggests => "recommends",
|
||||||
|
enhances => "supplements",
|
||||||
|
);
|
||||||
|
|
||||||
|
# specfile scriptlet => rpm tag name
|
||||||
|
my %script2tag = (
|
||||||
|
pre => "prein",
|
||||||
|
post => "postin",
|
||||||
|
preun => "preun",
|
||||||
|
postun => "postun",
|
||||||
|
pretrans => "pretrans",
|
||||||
|
posttrans => "posttrans",
|
||||||
|
verifyscript => "verifyscript",
|
||||||
|
# FIXME: triggers
|
||||||
|
);
|
||||||
|
|
||||||
|
# tags which are printed verbatim in the specfile
|
||||||
|
my @simple_tags = qw(version release license group summary packager vendor
|
||||||
|
url distribution);
|
||||||
|
|
||||||
|
sub load_package {
|
||||||
|
my $rpm = shift;
|
||||||
|
my %res;
|
||||||
|
|
||||||
|
for my $tag (qw(name arch sourcerpm description), @simple_tags) {
|
||||||
|
$res{$tag} = query_single($rpm, $tag);
|
||||||
|
}
|
||||||
|
my @files;
|
||||||
|
my @list = query_array($rpm, qw(filenames fileflags filemodes fileusername filegroupname filesizes filemtimes filelinktos));
|
||||||
|
for my $file (@list) {
|
||||||
|
push(@files, {
|
||||||
|
name => $file->[0],
|
||||||
|
flags => $file->[1],
|
||||||
|
mode => $file->[2],
|
||||||
|
owner => $file->[3],
|
||||||
|
group => $file->[4],
|
||||||
|
size => $file->[5],
|
||||||
|
mtime => $file->[6],
|
||||||
|
target => $file->[7],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
$res{files} = \@files;
|
||||||
|
while (my ($dep, $tag) = each(%dep2tag)) {
|
||||||
|
my @deps;
|
||||||
|
my @list = query_array($rpm, "${tag}name", "${tag}flags", "${tag}version");
|
||||||
|
for my $d (@list) {
|
||||||
|
next if $d->[0] eq "(none)";
|
||||||
|
push(@deps, {
|
||||||
|
name => $d->[0],
|
||||||
|
flags => $d->[1],
|
||||||
|
version => $d->[2],
|
||||||
|
});
|
||||||
|
}
|
||||||
|
$res{$dep} = \@deps;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (my ($script, $tag) = each(%script2tag)) {
|
||||||
|
my $s = query_single($rpm, $tag);
|
||||||
|
next unless $s && $s ne "(none)";
|
||||||
|
my $interp = query_single($rpm, "${tag}prog");
|
||||||
|
$res{$script} = {
|
||||||
|
interp => $interp,
|
||||||
|
script => $s,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
open(my $fh, '-|', "rpm", "-qp", "--changelog", $rpm) or die "rpm: $!\n";
|
||||||
|
{
|
||||||
|
local $/ = undef;
|
||||||
|
my $changelog = <$fh>;
|
||||||
|
close($fh);
|
||||||
|
$res{changelog} = $changelog;
|
||||||
|
}
|
||||||
|
|
||||||
|
return \%res;
|
||||||
|
}
|
||||||
|
|
||||||
|
# quote percent signs in text
|
||||||
|
sub quote {
|
||||||
|
my $text = shift;
|
||||||
|
|
||||||
|
$text =~ s/%/%%/g;
|
||||||
|
return $text;
|
||||||
|
}
|
||||||
|
|
||||||
|
sub print_package {
|
||||||
|
my ($p, $is_main) = @_;
|
||||||
|
|
||||||
|
if ($is_main) {
|
||||||
|
print SPEC "Name: $p->{name}\n";
|
||||||
|
print SPEC "Buildroot: $directory\n";
|
||||||
|
print SPEC "\%define _use_internal_dependency_generator 0\n";
|
||||||
|
print SPEC "\%define __find_provides %{nil}\n";
|
||||||
|
print SPEC "\%define __find_requires %{nil}\n";
|
||||||
|
print SPEC "\%define __find_supplements %{nil}\n";
|
||||||
|
if ($p->{nosource}) {
|
||||||
|
# We do not generate any no(src).rpm, but we want the
|
||||||
|
# %{sourcerpm} tag in the binary packages to match.
|
||||||
|
# So we add a dummy source and mark it as nosource.
|
||||||
|
print SPEC "Source0: repackage.spec\n";
|
||||||
|
print SPEC "NoSource: 0\n";
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
print SPEC "\%package -n $p->{name}\n";
|
||||||
|
}
|
||||||
|
for my $tag (@simple_tags) {
|
||||||
|
print SPEC "$tag: " . quote($p->{$tag}) . "\n";
|
||||||
|
}
|
||||||
|
print SPEC "BuildArch: noarch\n" if $p->{arch} eq "noarch";
|
||||||
|
for my $dep (keys(%dep2tag)) {
|
||||||
|
print_deps($dep, $p->{$dep});
|
||||||
|
}
|
||||||
|
print SPEC "\%description -n $p->{name}\n";
|
||||||
|
print SPEC quote($p->{description}) . "\n\n";
|
||||||
|
|
||||||
|
for my $script (keys(%script2tag)) {
|
||||||
|
next unless $p->{$script};
|
||||||
|
my $file = "$script-$p->{name}";
|
||||||
|
open(my $fh, '>', "$output/$file") or die "$output/$file: $!\n";
|
||||||
|
print SPEC "\%$script -p $p->{$script}{interp} -n $p->{name} -f $file\n";
|
||||||
|
print $fh $p->{$script}{script};
|
||||||
|
close($fh);
|
||||||
|
|
||||||
|
}
|
||||||
|
if ($p->{files}) {
|
||||||
|
print SPEC "\%files -n $p->{name}\n";
|
||||||
|
print_files($p->{files});
|
||||||
|
}
|
||||||
|
print SPEC "\n";
|
||||||
|
}
|
||||||
|
|
||||||
|
# /usr/include/rpm/rpmds.h
|
||||||
|
my %deptypes = (
|
||||||
|
pre => (1 << 9),
|
||||||
|
post => (1 << 10),
|
||||||
|
preun => (1 << 11),
|
||||||
|
postun => (1 << 12),
|
||||||
|
verify => (1 << 13),
|
||||||
|
);
|
||||||
|
my %depflags = (
|
||||||
|
"<" => (1 << 1),
|
||||||
|
">" => (1 << 2),
|
||||||
|
"=" => (1 << 3),
|
||||||
|
rpmlib => (1 << 24),
|
||||||
|
strong => (1 << 27),
|
||||||
|
);
|
||||||
|
|
||||||
|
sub print_deps {
|
||||||
|
my ($depname, $list) = @_;
|
||||||
|
|
||||||
|
foreach my $d (@$list) {
|
||||||
|
next if ($d->{flags} & $depflags{rpmlib});
|
||||||
|
|
||||||
|
if ($d->{flags} & $depflags{strong}) {
|
||||||
|
print SPEC $dep2strong{$depname};
|
||||||
|
} else {
|
||||||
|
print SPEC $depname;
|
||||||
|
}
|
||||||
|
my @deptypes;
|
||||||
|
while (my ($type, $bit) = each(%deptypes)) {
|
||||||
|
push(@deptypes, $type) if $d->{flags} & $bit;
|
||||||
|
}
|
||||||
|
print SPEC "(", join(",", @deptypes), ")" if @deptypes;
|
||||||
|
print SPEC ": ";
|
||||||
|
|
||||||
|
print SPEC quote($d->{name});
|
||||||
|
if ($d->{version}) {
|
||||||
|
print SPEC " ";
|
||||||
|
for my $op (qw(< > =)) {
|
||||||
|
print SPEC $op if $d->{flags} & $depflags{$op};
|
||||||
|
}
|
||||||
|
print SPEC " " . quote($d->{version});
|
||||||
|
}
|
||||||
|
print SPEC "\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
# /usr/include/rpm/rpmfi.h
|
||||||
|
my %filetypes = (
|
||||||
|
config => (1 << 0),
|
||||||
|
doc => (1 << 1),
|
||||||
|
missingok => (1 << 3),
|
||||||
|
noreplace => (1 << 4),
|
||||||
|
ghost => (1 << 6),
|
||||||
|
);
|
||||||
|
|
||||||
|
sub print_files {
|
||||||
|
my $files = shift;
|
||||||
|
|
||||||
|
for my $f (@$files) {
|
||||||
|
my $path = "$directory/$f->{name}";
|
||||||
|
my $attrs = "";
|
||||||
|
# Fix mtime of directories, which cpio -idm fails to preserve
|
||||||
|
if (S_ISDIR($f->{mode})) {
|
||||||
|
$attrs .= "\%dir ";
|
||||||
|
utime($f->{mtime}, $f->{mtime}, $path);
|
||||||
|
}
|
||||||
|
$attrs .= sprintf('%%attr(%04o, %s, %s) ', ($f->{mode} & 0777),
|
||||||
|
$f->{owner}, $f->{group});
|
||||||
|
if ($f->{flags} & $filetypes{config}) {
|
||||||
|
$attrs .= "%config ";
|
||||||
|
my @cfg_attrs;
|
||||||
|
for my $attr (qw(missingok noreplace)) {
|
||||||
|
next unless $f->{flags} & $filetypes{$attr};
|
||||||
|
push(@cfg_attrs, $attr);
|
||||||
|
}
|
||||||
|
$attrs .= "(" . join(",", @cfg_attrs) . ")" if @cfg_attrs;
|
||||||
|
}
|
||||||
|
$attrs .= "%doc " if $f->{flags} & $filetypes{doc};
|
||||||
|
if ($f->{flags} & $filetypes{ghost}) {
|
||||||
|
$attrs .= "%ghost ";
|
||||||
|
if (S_ISREG($f->{mode})) {
|
||||||
|
open(my $fh, '>', $path) or die "$path: $!\n";
|
||||||
|
if ($f->{size} > 0) {
|
||||||
|
sysseek($fh, $f->{size} - 1, SEEK_SET);
|
||||||
|
syswrite($fh, ' ', 1);
|
||||||
|
}
|
||||||
|
close($fh);
|
||||||
|
utime($f->{mtime}, $f->{mtime}, $path);
|
||||||
|
} elsif (S_ISLNK($f->{mode})) {
|
||||||
|
symlink($f->{target}, $path);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
# mtime of symlinks is also not preserved by cpio
|
||||||
|
if (S_ISLNK($f->{mode})) {
|
||||||
|
# perl core does not provide lutimes()/utimensat()
|
||||||
|
system("touch", "-h", "-d\@$f->{mtime}", $path);
|
||||||
|
}
|
||||||
|
|
||||||
|
print SPEC "$attrs " . quote($f->{name}) . "\n";
|
||||||
|
if (-e "$path.sig") {
|
||||||
|
print SPEC "$attrs " . quote($f->{name}) . ".sig\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
my %packages;
|
||||||
|
for my $rpm (@rpms) {
|
||||||
|
my $p = load_package($rpm);
|
||||||
|
$packages{$p->{name}} = $p;
|
||||||
|
}
|
||||||
|
|
||||||
|
my $sourcerpm;
|
||||||
|
for my $p (values(%packages)) {
|
||||||
|
$sourcerpm = $p->{sourcerpm} unless $sourcerpm;
|
||||||
|
if ($p->{sourcerpm} ne $sourcerpm) {
|
||||||
|
die "Error: packages built from different source rpm: $sourcerpm vs $p->{sourcerpm}\n";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if ($sourcerpm !~ /^(.+)-([^-]+)-([^-]+)\.(no)?src\.rpm$/) {
|
||||||
|
die "Error: malformed %{sourcerpm} tag: $sourcerpm\n";
|
||||||
|
}
|
||||||
|
my ($main_name, $main_ver, $main_rel, $nosrc) = ($1, $2, $3, $4);
|
||||||
|
if (!exists($packages{$main_name})) {
|
||||||
|
# create an empty main package
|
||||||
|
my $first = (values(%packages))[0];
|
||||||
|
$packages{$main_name} = {
|
||||||
|
name => $main_name,
|
||||||
|
version => $main_ver,
|
||||||
|
release => $main_rel,
|
||||||
|
};
|
||||||
|
for my $tag (qw(description changelog arch), @simple_tags) {
|
||||||
|
next if $packages{$main_name}->{$tag};
|
||||||
|
$packages{$main_name}->{$tag} = $first->{$tag};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
$packages{$main_name}->{nosource} = $nosrc ? 1 : 0;
|
||||||
|
|
||||||
|
open(SPEC, '>', "$output/repackage.spec") or die "$output/repackage.spec: $!\n";
|
||||||
|
print_package($packages{$main_name}, 1);
|
||||||
|
for my $p (values(%packages)) {
|
||||||
|
next if $p->{name} eq $main_name;
|
||||||
|
print_package($p, 0);
|
||||||
|
}
|
||||||
|
print SPEC "\%changelog\n";
|
||||||
|
print SPEC quote($packages{$main_name}->{changelog});
|
||||||
|
close(SPEC);
|
110
pesign-install-post
Normal file
110
pesign-install-post
Normal file
@ -0,0 +1,110 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# This script is run by rpmbuild at the end of install section. It computes
|
||||||
|
# hashes of files listed in the %sign_files macro and stores them in
|
||||||
|
# %_topdir/OTHER/%name.cpio.rsasign. It also puts a specfile there, that
|
||||||
|
# is later used to repackage the RPMs.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2013 SUSE Linux Products GmbH, Nuernberg, Germany.
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
|
|
||||||
|
set -e
|
||||||
|
|
||||||
|
files=
|
||||||
|
output=
|
||||||
|
while test $# -gt 0; do
|
||||||
|
case "$1" in
|
||||||
|
--files)
|
||||||
|
files=$2
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
--output)
|
||||||
|
output=$2
|
||||||
|
shift 2
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "$0: Unknown option: $1" >&2
|
||||||
|
exit 1
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
if test -z "$files"; then
|
||||||
|
exit 0
|
||||||
|
fi
|
||||||
|
if test -z "$output"; then
|
||||||
|
echo "$0: --output not specified" >&2
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
if test -z "$RPM_BUILD_ROOT"; then
|
||||||
|
echo "$0: warning: \$RPM_BUILD_ROOT not set, using the root directory" >&2
|
||||||
|
RPM_BUILD_ROOT=/
|
||||||
|
fi
|
||||||
|
|
||||||
|
mkdir -p "$output"
|
||||||
|
cert=$RPM_SOURCE_DIR/_projectcert.crt
|
||||||
|
if test -e "$cert"; then
|
||||||
|
echo "Using signing certificate $cert"
|
||||||
|
else
|
||||||
|
echo "No buildservice signing certificate"
|
||||||
|
cert=/dev/null
|
||||||
|
fi
|
||||||
|
sed "
|
||||||
|
s:@NAME@:$RPM_PACKAGE_NAME:g
|
||||||
|
/@CERT@/ {
|
||||||
|
r $cert
|
||||||
|
d
|
||||||
|
}
|
||||||
|
" /usr/lib/rpm/pesign-repackage.spec.in >"$output/pesign-repackage.spec"
|
||||||
|
|
||||||
|
cd "$RPM_BUILD_ROOT"
|
||||||
|
args=()
|
||||||
|
for pattern in $files; do
|
||||||
|
pattern=${pattern#/}
|
||||||
|
if test "${pattern:0:2}" != "./"; then
|
||||||
|
pattern="./$pattern"
|
||||||
|
fi
|
||||||
|
if test -d "$pattern"; then
|
||||||
|
pattern="$pattern/*"
|
||||||
|
fi
|
||||||
|
args=("${args[@]}" -o -path "$pattern")
|
||||||
|
done
|
||||||
|
# delete the leading -o
|
||||||
|
unset args[0]
|
||||||
|
|
||||||
|
archive=$output/$RPM_PACKAGE_NAME.cpio.rsasign
|
||||||
|
archive_dir=$output/$RPM_PACKAGE_NAME
|
||||||
|
mkdir -p "$archive_dir"
|
||||||
|
# create an empty nss database to make pesign happy
|
||||||
|
nss_db=$(mktemp -d)
|
||||||
|
trap 'rm -rf "$nss_db"' EXIT
|
||||||
|
echo >"$nss_db/password"
|
||||||
|
certutil -N -f "$nss_db/password" -d "$nss_db"
|
||||||
|
|
||||||
|
echo "Creating $archive"
|
||||||
|
files=($(find . -type f \( "${args[@]}" \)))
|
||||||
|
for f in "${files[@]}"; do
|
||||||
|
dest="$archive_dir/$f"
|
||||||
|
mkdir -p "${dest%/*}"
|
||||||
|
case "$f" in
|
||||||
|
./boot/* | *.efi)
|
||||||
|
pesign --certdir="$nss_db" -i "$f" --digestdata "$dest"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
cp "$f" "$dest"
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
cd "$archive_dir"
|
||||||
|
find . -type f | cpio -H newc -o >"$archive"
|
||||||
|
rm -rf "$archive_dir"
|
||||||
|
|
45
pesign-obs-integration.changes
Normal file
45
pesign-obs-integration.changes
Normal file
@ -0,0 +1,45 @@
|
|||||||
|
-------------------------------------------------------------------
|
||||||
|
Wed Jan 30 09:47:25 UTC 2013 - mmarek@suse.cz
|
||||||
|
|
||||||
|
- Version 6
|
||||||
|
- Fix handling packages with NoSource
|
||||||
|
- Fix for multiple patterns in %sign_files
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
Tue Jan 29 13:44:43 UTC 2013 - mmarek@suse.cz
|
||||||
|
|
||||||
|
- Version 5
|
||||||
|
- Use newc-style cpio archives, as required by the buildservice.
|
||||||
|
- Use signing certificates provided by the buildservice.
|
||||||
|
- Minor fixes.
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
Mon Jan 28 15:01:17 UTC 2013 - mmarek@suse.cz
|
||||||
|
|
||||||
|
- Version 4
|
||||||
|
- Support for firmware signatures.
|
||||||
|
- Expect the correct archive with signatures (<name>.cpio.rsasign.sig).
|
||||||
|
- Minor fixes.
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
Wed Jan 23 22:01:40 UTC 2013 - mmarek@suse.cz
|
||||||
|
|
||||||
|
- Version 3
|
||||||
|
- Switch to storing whole files in the *.cpio.rsasign archive.
|
||||||
|
- Append the signatures to kernel modules.
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
Fri Jan 18 12:51:17 UTC 2013 - mmarek@suse.cz
|
||||||
|
|
||||||
|
- Version 2
|
||||||
|
- Generates another specfile in pesign-repackage.spec to
|
||||||
|
be able to copy nearly all RPM tags from the original packages.
|
||||||
|
- Changed to only store sha256 hashes in the *.cpio.rsasign file,
|
||||||
|
instead of whole files.
|
||||||
|
|
||||||
|
-------------------------------------------------------------------
|
||||||
|
Thu Dec 13 12:06:00 UTC 2012 - mmarek@suse.com
|
||||||
|
|
||||||
|
- Created package with macros and scripts to integrate kernel and
|
||||||
|
bootloader signing into OBS (fate#314552).
|
||||||
|
|
77
pesign-obs-integration.spec
Normal file
77
pesign-obs-integration.spec
Normal file
@ -0,0 +1,77 @@
|
|||||||
|
#
|
||||||
|
# spec file for package pesign-obs-integration (Version 1.0)
|
||||||
|
#
|
||||||
|
# Copyright (c) 2013 SUSE LINUX Products GmbH, Nuernberg, Germany.
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
|
#
|
||||||
|
# Please submit bugfixes or comments via http://bugs.opensuse.org/
|
||||||
|
#
|
||||||
|
|
||||||
|
# norootforbuild
|
||||||
|
# needssslcertforbuild
|
||||||
|
|
||||||
|
Name: pesign-obs-integration
|
||||||
|
Summary: Macros and scripts to sign the kernel and bootloader
|
||||||
|
Version: 6.0
|
||||||
|
Release: 1
|
||||||
|
Requires: openssl mozilla-nss-tools
|
||||||
|
%ifarch %ix86 x86_64 ia64
|
||||||
|
Requires: pesign
|
||||||
|
%endif
|
||||||
|
BuildRequires: openssl
|
||||||
|
License: GPL v2 only
|
||||||
|
Group: Development/Tools/Other
|
||||||
|
URL: http://en.opensuse.org/openSUSE:UEFI_Image_File_Sign_Tools
|
||||||
|
Source1: macros.pesign-obs
|
||||||
|
Source2: pesign-repackage.spec.in
|
||||||
|
Source3: pesign-gen-repackage-spec
|
||||||
|
Source4: pesign-install-post
|
||||||
|
Source5: COPYING
|
||||||
|
Source6: README
|
||||||
|
Source7: kernel-sign-file
|
||||||
|
BuildRoot: %{_tmppath}/%{name}-%{version}-build
|
||||||
|
%description
|
||||||
|
This package provides scripts and rpm macros to automate signing of the
|
||||||
|
boot loader, kernel and kernel modules in the openSUSE Buildservice.
|
||||||
|
|
||||||
|
%prep
|
||||||
|
%setup -cT
|
||||||
|
cp %_sourcedir/{COPYING,README} .
|
||||||
|
|
||||||
|
%build
|
||||||
|
|
||||||
|
%install
|
||||||
|
|
||||||
|
mkdir -p %buildroot/usr/lib/rpm %buildroot/etc/rpm
|
||||||
|
cd %_sourcedir
|
||||||
|
install -m644 macros.pesign-obs %buildroot/etc/rpm
|
||||||
|
install pesign-gen-repackage-spec pesign-install-post kernel-sign-file %buildroot/usr/lib/rpm
|
||||||
|
install -m644 pesign-repackage.spec.in %buildroot/usr/lib/rpm
|
||||||
|
if test -e _projectcert.crt; then
|
||||||
|
openssl x509 -inform PEM -in _projectcert.crt \
|
||||||
|
-outform DER -out %buildroot/usr/lib/rpm/pesign-cert.x509
|
||||||
|
else
|
||||||
|
echo "No buildservice project certificate available"
|
||||||
|
fi
|
||||||
|
|
||||||
|
%files
|
||||||
|
%defattr(-,root,root)
|
||||||
|
%doc COPYING README
|
||||||
|
/usr/lib/rpm/*
|
||||||
|
/etc/rpm/*
|
||||||
|
|
||||||
|
%changelog
|
||||||
|
|
109
pesign-repackage.spec.in
Normal file
109
pesign-repackage.spec.in
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
# This specfile unpacks the original RPMs, runs pesign-gen-repackage-spec
|
||||||
|
# to create a second repackage specfile, and runs another rpmbuild to
|
||||||
|
# actually do the repackaging.
|
||||||
|
#
|
||||||
|
# Copyright (c) 2013 SUSE Linux Products GmbH, Nuernberg, Germany.
|
||||||
|
#
|
||||||
|
# This program is free software; you can redistribute it and/or modify
|
||||||
|
# it under the terms of the GNU General Public License as published by
|
||||||
|
# the Free Software Foundation; either version 2 of the License, or
|
||||||
|
# (at your option) any later version.
|
||||||
|
#
|
||||||
|
# This program is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU General Public License
|
||||||
|
# along with this program; if not, write to the Free Software
|
||||||
|
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA
|
||||||
|
|
||||||
|
# Do not generate any debug packages from the repackage specfile
|
||||||
|
%undefine _build_create_debug
|
||||||
|
|
||||||
|
Name: pesign-repackage
|
||||||
|
Version: 1.0
|
||||||
|
Release: 1
|
||||||
|
BuildRequires: openssl mozilla-nss-tools
|
||||||
|
%ifarch %ix86 x86_64 ia64
|
||||||
|
BuildRequires: pesign
|
||||||
|
%endif
|
||||||
|
License: GPLv
|
||||||
|
Group: Development/Tools/Other
|
||||||
|
Summary: Spec file to rebuild RPMs with signatures
|
||||||
|
BuildRoot: %{_tmppath}/%{name}-%{version}-build
|
||||||
|
%description
|
||||||
|
Rebuilds RPMs with signatures
|
||||||
|
|
||||||
|
%prep
|
||||||
|
%setup -c -T
|
||||||
|
|
||||||
|
%build
|
||||||
|
|
||||||
|
%install
|
||||||
|
|
||||||
|
pushd %buildroot
|
||||||
|
disturl=
|
||||||
|
rpms=()
|
||||||
|
for rpm in %_sourcedir/*.rpm; do
|
||||||
|
case "$rpm" in
|
||||||
|
*.src.rpm | *.nosrc.rpm)
|
||||||
|
cp "$rpm" %_srcrpmdir/
|
||||||
|
continue
|
||||||
|
esac
|
||||||
|
rpm2cpio "$rpm" | cpio -idm
|
||||||
|
d=$(rpm -qp --qf '%%{disturl}' "$rpm")
|
||||||
|
if test -z "$disturl"; then
|
||||||
|
disturl=$d
|
||||||
|
fi
|
||||||
|
if test "$disturl" != "$d"; then
|
||||||
|
echo "Error: packages have different disturl: $d vs $disturl"
|
||||||
|
exit 1
|
||||||
|
fi
|
||||||
|
rpms=("${rpms[@]}" "$rpm")
|
||||||
|
done
|
||||||
|
popd
|
||||||
|
mkdir rsasigned
|
||||||
|
pushd rsasigned
|
||||||
|
cpio -idm <%_sourcedir/@NAME@.cpio.rsasign.sig
|
||||||
|
cat >cert.crt <<EOF
|
||||||
|
@CERT@
|
||||||
|
EOF
|
||||||
|
if test "$(wc -l <cert.crt)" -gt 1; then
|
||||||
|
openssl x509 -inform PEM -in cert.crt -outform DER -out cert.x509
|
||||||
|
cert=cert.x509
|
||||||
|
else
|
||||||
|
echo "warning: No buildservice project certificate found, add"
|
||||||
|
echo "warning: # needssslcertforbuild to the specfile"
|
||||||
|
echo "warning: Using /usr/lib/rpm/pesign-cert.x509 as fallback"
|
||||||
|
cert=/usr/lib/rpm/pesign-cert.x509
|
||||||
|
fi
|
||||||
|
sigs=($(find -type f -name '*.sig'))
|
||||||
|
for sig in "${sigs[@]}"; do
|
||||||
|
f=%buildroot/${sig%.sig}
|
||||||
|
case "$sig" in
|
||||||
|
*.ko.sig)
|
||||||
|
/usr/lib/rpm/kernel-sign-file -s "$sig" sha256 "$cert" "$f"
|
||||||
|
;;
|
||||||
|
./lib/firmware/*.sig)
|
||||||
|
/usr/lib/rpm/kernel-sign-file -f -s "$sig" sha256 "$cert" "$f"
|
||||||
|
;;
|
||||||
|
*)
|
||||||
|
echo "Warning: unhandled signature: $sig" >&2
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
popd
|
||||||
|
/usr/lib/rpm/pesign-gen-repackage-spec --directory=%buildroot "${rpms[@]}"
|
||||||
|
rpmbuild --define "%%buildroot %buildroot" --define "%%disturl $disturl" \
|
||||||
|
--define "%%_builddir $PWD" \
|
||||||
|
--define "%_suse_insert_debug_package %%{nil}" -bb repackage.spec
|
||||||
|
|
||||||
|
# This is needed by the kernel packages. Ideally, we should not run _any_ brp
|
||||||
|
# checks, because the RPMs passed them once already
|
||||||
|
export NO_BRP_STALE_LINK_ERROR=yes
|
||||||
|
|
||||||
|
# Make sure that our rpmbuild does not complain about unpackaged files
|
||||||
|
rm -rf %buildroot
|
||||||
|
mkdir %buildroot
|
||||||
|
|
Loading…
x
Reference in New Issue
Block a user