-# $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 <bsd.own.mk>
OpenBSD/Ustar.pm \
OpenBSD/Vstat.pm \
OpenBSD/md5.pm \
+ OpenBSD/signify.pm \
OpenBSD/x509.pm
PACKAGEDIRS=OpenBSD OpenBSD/PackageRepository OpenBSD/ProgressMeter \
# 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 <espie@openbsd.org>
#
$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;
# 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 <espie@openbsd.org>
#
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;
# 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 <espie@openbsd.org>
#
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' }
#! /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 <espie@openbsd.org>
#
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;
}
sub new_sig
{
require OpenBSD::x509;
- return OpenBSD::PackingElement::DigitalSignature->new_x509;
+ return OpenBSD::PackingElement::DigitalSignature->blank('x509');
}
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);
$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...');
{
}
+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) = @_;
{
}
-
package OpenBSD::PackingElement::Cwd;
sub archive
{
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);
return '!%%'.shift->{name}.'%%';
}
-
# put together file and filename, in order to handle fragments simply
package MyFile;
sub new
{
my ($self, $plist, $state) = @_;
-
if ($plist->has('digital-signature')) {
if ($state->defines('resign')) {
$state->errsay("Resigning #1", $plist->pkgname);
$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;
}
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;
--- /dev/null
+# ex:ts=8 sw=4:
+# $OpenBSD: signify.pm,v 1.1 2013/12/31 11:21:10 espie Exp $
+#
+# Copyright (c) 2013 Marc Espie <espie@openbsd.org>
+#
+# 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;