From 645b1fe32a71ce08a0f2bae9223197dffd4b543d Mon Sep 17 00:00:00 2001 From: espie Date: Tue, 31 Dec 2013 11:21:10 +0000 Subject: [PATCH] signify support --- usr.sbin/pkg_add/Makefile | 3 +- usr.sbin/pkg_add/OpenBSD/PackingElement.pm | 9 +-- usr.sbin/pkg_add/OpenBSD/PackingList.pm | 5 +- usr.sbin/pkg_add/OpenBSD/Paths.pm | 4 +- usr.sbin/pkg_add/OpenBSD/PkgCreate.pm | 88 ++++++++++++++++++---- usr.sbin/pkg_add/OpenBSD/signify.pm | 84 +++++++++++++++++++++ 6 files changed, 170 insertions(+), 23 deletions(-) create mode 100644 usr.sbin/pkg_add/OpenBSD/signify.pm diff --git a/usr.sbin/pkg_add/Makefile b/usr.sbin/pkg_add/Makefile index 69c22f30d83..11ac046406c 100644 --- a/usr.sbin/pkg_add/Makefile +++ b/usr.sbin/pkg_add/Makefile @@ -1,4 +1,4 @@ -# $OpenBSD: Makefile,v 1.76 2012/08/06 00:00:28 fgsch Exp $ +# $OpenBSD: Makefile,v 1.77 2013/12/31 11:21:10 espie Exp $ .include @@ -66,6 +66,7 @@ PACKAGES= \ OpenBSD/Ustar.pm \ OpenBSD/Vstat.pm \ OpenBSD/md5.pm \ + OpenBSD/signify.pm \ OpenBSD/x509.pm PACKAGEDIRS=OpenBSD OpenBSD/PackageRepository OpenBSD/ProgressMeter \ diff --git a/usr.sbin/pkg_add/OpenBSD/PackingElement.pm b/usr.sbin/pkg_add/OpenBSD/PackingElement.pm index 3258adb7542..66b90e3a804 100644 --- a/usr.sbin/pkg_add/OpenBSD/PackingElement.pm +++ b/usr.sbin/pkg_add/OpenBSD/PackingElement.pm @@ -1,5 +1,5 @@ # ex:ts=8 sw=4: -# $OpenBSD: PackingElement.pm,v 1.214 2013/12/30 09:14:49 espie Exp $ +# $OpenBSD: PackingElement.pm,v 1.215 2013/12/31 11:21:10 espie Exp $ # # Copyright (c) 2003-2010 Marc Espie # @@ -1805,13 +1805,12 @@ sub new $class; } -sub new_x509 +sub blank { - my ($class) = @_; - bless { key => 'x509', timestamp => time, b64sig => '' }, $class; + my ($class, $type) = @_; + bless { key => $type, timestamp => time, b64sig => '' }, $class; } - sub stringize { my $self = shift; diff --git a/usr.sbin/pkg_add/OpenBSD/PackingList.pm b/usr.sbin/pkg_add/OpenBSD/PackingList.pm index 1afa73eb313..a965fc09e85 100644 --- a/usr.sbin/pkg_add/OpenBSD/PackingList.pm +++ b/usr.sbin/pkg_add/OpenBSD/PackingList.pm @@ -1,5 +1,5 @@ # ex:ts=8 sw=4: -# $OpenBSD: PackingList.pm,v 1.123 2013/12/30 09:14:49 espie Exp $ +# $OpenBSD: PackingList.pm,v 1.124 2013/12/31 11:21:10 espie Exp $ # # Copyright (c) 2003-2010 Marc Espie # @@ -538,6 +538,9 @@ sub check_signature if ($sig->{key} eq 'x509') { require OpenBSD::x509; return OpenBSD::x509::check_signature($plist, $state); + } elsif ($sig->{key} eq 'signify') { + require OpenBSD::signify; + return OpenBSD::signify::check_signature($plist, $state); } else { $state->log("Error: unknown signature style $sig->{key}"); return 0; diff --git a/usr.sbin/pkg_add/OpenBSD/Paths.pm b/usr.sbin/pkg_add/OpenBSD/Paths.pm index 00a9cac9931..1d779139304 100644 --- a/usr.sbin/pkg_add/OpenBSD/Paths.pm +++ b/usr.sbin/pkg_add/OpenBSD/Paths.pm @@ -1,5 +1,5 @@ # ex:ts=8 sw=4: -# $OpenBSD: Paths.pm,v 1.21 2012/01/16 08:42:38 schwarze Exp $ +# $OpenBSD: Paths.pm,v 1.22 2013/12/31 11:21:10 espie Exp $ # # Copyright (c) 2007 Marc Espie # @@ -32,6 +32,8 @@ sub groupadd() { '/usr/sbin/groupadd' } sub sysctl() { '/sbin/sysctl' } sub openssl() { '/usr/sbin/openssl' } sub pkgca() { '/etc/ssl/pkgca.pem' } +sub signify() { '/usr/bin/signify' } +sub signifykey() { '/etc/openbsd.pubkey' } sub pkg_add() { '/usr/sbin/pkg_add' } sub chmod() { '/bin/chmod' } # external command is used for symbolic modes. sub gzip() { '/usr/bin/gzip' } diff --git a/usr.sbin/pkg_add/OpenBSD/PkgCreate.pm b/usr.sbin/pkg_add/OpenBSD/PkgCreate.pm index 9e4443e843a..6be24079ef2 100644 --- a/usr.sbin/pkg_add/OpenBSD/PkgCreate.pm +++ b/usr.sbin/pkg_add/OpenBSD/PkgCreate.pm @@ -1,6 +1,6 @@ #! /usr/bin/perl # ex:ts=8 sw=4: -# $OpenBSD: PkgCreate.pm,v 1.75 2013/12/30 09:14:49 espie Exp $ +# $OpenBSD: PkgCreate.pm,v 1.76 2013/12/31 11:21:10 espie Exp $ # # Copyright (c) 2003-2010 Marc Espie # @@ -23,13 +23,33 @@ use OpenBSD::AddCreateDelete; use OpenBSD::Dependencies; use OpenBSD::SharedLibs; +package Signer; + +my $h = { + x509 => 'Signer::X509', + signify => 'Signer::SIGNIFY', +}; + +sub factory +{ + my ($class, $state) = @_; + + my @p = @{$state->{signature_params}}; + + if (defined $h->{$p[0]}) { + return $h->{$p[0]}->new($state, @p); + } else { + $state->usage("Unknown signature scheme $p[0]"); + } +} + package Signer::X509; sub new { my ($class, $state, @p) = @_; if (@p != 3 || !-f $p[1] || !-f $p[2]) { - $state->usage("x509 signature wants -s cert -s privkey"); + $state->usage("$p[0] signature wants -s cert -s privkey"); } bless {cert => $p[1], privkey => $p[2]}, $class; } @@ -37,7 +57,7 @@ sub new sub new_sig { require OpenBSD::x509; - return OpenBSD::PackingElement::DigitalSignature->new_x509; + return OpenBSD::PackingElement::DigitalSignature->blank('x509'); } sub compute_signature @@ -47,6 +67,30 @@ sub compute_signature $self->{privkey}); } +package Signer::SIGNIFY; +sub new +{ + my ($class, $state, @p) = @_; + if (@p != 2 || !-f $p[1]) { + $state->usage("$p[0] signature wants -s privkey"); + } + + bless {privkey => $p[1]}, $class; +} + +sub new_sig +{ + require OpenBSD::signify; + return OpenBSD::PackingElement::DigitalSignature->blank('signify'); +} + +sub compute_signature +{ + my ($self, $state, $plist) = @_; + return OpenBSD::signify::compute_signature($plist, $state, + $self->{privkey}); +} + package OpenBSD::PkgCreate::State; our @ISA = qw(OpenBSD::AddCreateDelete::State); @@ -146,7 +190,7 @@ sub handle_options $state->SUPER::handle_options('p:f:d:M:U:s:A:B:P:W:qQo:S:', '[-nQqvx] [-A arches] [-B pkg-destdir] [-D name[=value]]', '[-L localbase] [-M displayfile] [-P pkg-dependency]', - '[-s [x509|sos] -s cert -s priv] [-o dir] [-S source]', + '[-s [x509 -s cert|signify] -s priv] [-o dir] [-S source]', '[-U undisplayfile] [-W wantedlib]', '[-d desc -D COMMENT=value -f packinglist -p prefix]', 'pkg-name...'); @@ -219,6 +263,15 @@ sub verify_checksum { } +sub register_forbidden +{ + my ($self, $state) = @_; + if ($self->is_forbidden) { + push(@{$state->{forbidden}}, $self); + } +} + +sub is_forbidden() { 0 } sub resolve_link { my ($filename, $base, $level) = @_; @@ -413,7 +466,6 @@ sub verify_checksum { } - package OpenBSD::PackingElement::Cwd; sub archive { @@ -654,6 +706,12 @@ sub find_every_library push(@{$h->{$l[0]}{dynamic}}, $self); } +package OpenBSD::PackingElement::DigitalSignature; +sub is_forbidden() { 1 } + +package OpenBSD::PackingElement::Url; +sub is_forbidden() { 1 } + package OpenBSD::PackingElement::Fragment; our @ISA=qw(OpenBSD::PackingElement); @@ -671,7 +729,6 @@ sub stringize return '!%%'.shift->{name}.'%%'; } - # put together file and filename, in order to handle fragments simply package MyFile; sub new @@ -1062,7 +1119,6 @@ sub add_signature { my ($self, $plist, $state) = @_; - if ($plist->has('digital-signature')) { if ($state->defines('resign')) { $state->errsay("Resigning #1", $plist->pkgname); @@ -1222,18 +1278,25 @@ sub create_plist $pkgname = $1; $pkgname =~ s/\.tgz$//o; } - $plist->set_pkgname($pkgname); $state->say("Creating package #1", $pkgname) if !(defined $state->opt('q')) && $state->opt('v'); if (!$state->opt('q')) { $plist->set_infodir(OpenBSD::Temp->dir); } - $self->add_elements($plist, $state); unless (defined $state->opt('q') && defined $state->opt('n')) { $state->set_status("reading plist"); } + $plist->set_pkgname($pkgname); + $self->add_elements($plist, $state); $self->read_all_fragments($state, $plist); + $plist->register_forbidden($state); + if (defined $state->{forbidden}) { + for my $e (@{$state->{forbidden}}) { + $state->errsay("Error: #1 can't be set explicitly", "\@".$e->keyword." ".$e->stringize); + } + $state->fatal("Can't continue"); + } return $plist; } @@ -1386,12 +1449,7 @@ sub parse_and_run try { if (defined $state->{signature_params}) { - my @p = @{$state->{signature_params}}; - if ($p[0] eq 'x509') { - $state->{signer} = Signer::X509->new($state, @p); - } else { - $state->usage("Unknown signature scheme $p[0]"); - } + $state->{signer} = Signer->factory($state); } if (defined $state->opt('Q')) { $state->{opt}{q} = 1; diff --git a/usr.sbin/pkg_add/OpenBSD/signify.pm b/usr.sbin/pkg_add/OpenBSD/signify.pm new file mode 100644 index 00000000000..e1ed4a4f31c --- /dev/null +++ b/usr.sbin/pkg_add/OpenBSD/signify.pm @@ -0,0 +1,84 @@ +# ex:ts=8 sw=4: +# $OpenBSD: signify.pm,v 1.1 2013/12/31 11:21:10 espie Exp $ +# +# Copyright (c) 2013 Marc Espie +# +# Permission to use, copy, modify, and distribute this software for any +# purpose with or without fee is hereby granted, provided that the above +# copyright notice and this permission notice appear in all copies. +# +# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. + +use strict; +use warnings; + +package OpenBSD::signify; + +use OpenBSD::PackageInfo; +use OpenBSD::Paths; +use File::Temp qw/mkstemp/; + +my $header = "signify -- signature\n"; +my $cmd = OpenBSD::Paths->signify; +my $defaultpubkey = OpenBSD::Paths->signifykey; +my $suffix = ".sig"; + +sub compute_signature +{ + my ($plist, $state, $key) = @_; + + my $contents = $plist->infodir.CONTENTS; + my $sigfile = $contents.$suffix; + + open my $fh, ">", $contents; + $plist->write_no_sig($fh); + close $fh; + $state->system($cmd, '-I', $contents, '-S', $key, '-V', 'sign') + == 0 or die "probleme generating signature"; + open(my $sighandle, '<', $sigfile) + or die "problem reading signature"; + my $header = <$sighandle>; + my $sig = <$sighandle>; + close($sighandle); + unlink($sigfile); + chomp $sig; + return $sig; +} + +sub check_signature +{ + my ($plist, $state) = @_; + my $sig = $plist->get('digital-signature'); + my ($fh, $fname) = mkstemp("/tmp/pkgcontent.XXXXXXXXX"); + $plist->write_no_sig($fh); + open(my $fh2, ">", $fname.$suffix); + print $fh2 $header, $sig->{b64sig}, "\n"; + close $fh; + close $fh2; + my $pubkey = $defaultpubkey; + if ($plist->has('vendor')) { + my $vendor = $plist->get('vendor')->name; + $pubkey = "/etc/signify/$vendor.pubkey"; + if (!-f $pubkey) { + $state->say("Unknown vendor #1", $vendor); + return 0; + } + } + if ($state->system(sub { open STDERR, ">", "/dev/null"; + open STDOUT, ">", "/dev/null";}, + $cmd, '-I', $fname, '-P', $pubkey, '-V', 'verify') != 0) { + $state->log("Bad signature"); + return 0; + } + unlink $fname; + unlink $fname.$suffix; + return 1; +} + +1; -- 2.20.1