Commit 3d35061c authored by Leigh B Stoller's avatar Leigh B Stoller

Add geni_trustroots option to GetVersion, which returns the set of

federation trust roots for the aggregate. 

Moved SplitCertBundle bundle into GeniCertificate since we do this in
multiple places.
parent 790824f4
......@@ -232,6 +232,24 @@ sub GetVersion()
"geni_version" => $coder->string("3")}
];
}
if (defined($options) && exists($options->{'geni_trustroots'})) {
my @roots = ();
my @certs = GeniCertificate::SplitCertBundle("$TB/etc/genica.bundle");
foreach my $root (@certs) {
my $cert = GeniCertificate->LoadFromString($root);
next
if (!defined($cert));
next
if (!defined($cert->urn()));
push(@roots, {"CN" => $cert->CommonName(),
"Serial" => $cert->serial(),
"Expires" => $cert->enddate(),
"SubjAltNameURIs" => [$cert->urn()],
});
}
$blob->{"geni_trustroots"} = \@roots;
}
my $response = GeniResponse->Create(GENIRESPONSE_SUCCESS, $blob);
if ($API_VERSION > 1) {
$response->{"geni_api"} = $API_VERSION;
......
......@@ -43,12 +43,13 @@ use vars qw(@ISA @EXPORT);
use GeniDB;
use GeniResponse;
use GeniHRN;
use emutil qw(TBGetUniqueIndex);
use emutil;
use English;
use XML::Simple;
use XML::LibXML;
use Crypt::X509;
use Crypt::OpenSSL::X509;
use Date::Parse;
use Data::Dumper;
use File::Temp qw(tempfile);
use Carp qw(cluck);
......@@ -651,6 +652,9 @@ sub LoadFromArray($$@)
$self->{'CERT'}->{'created'} = undef;
$self->{'CERT'}->{'uri'} = $url;
$self->{'CERT'}->{'urn'} = $urn;
$self->{'CERT'}->{'startdate'} = undef;
$self->{'CERT'}->{'enddate'} = undef;
$self->{'CERT'}->{'serial'} = undef;
# Convert URNs to objects.
$self->{'CERT'}->{'urnOBJ'} = GeniHRN->new($urn) if (defined($urn));
......@@ -760,6 +764,9 @@ sub LoadFromStringFast($$)
$self->{'CERT'}->{'uri'} = undef;;
$self->{'CERT'}->{'urn'} = $urn;
$self->{'CERT'}->{'certfile'} = undef;
$self->{'CERT'}->{'startdate'} = TBDateStringGMT($x509->notBefore());
$self->{'CERT'}->{'enddate'} = TBDateStringGMT($x509->notAfter());
$self->{'CERT'}->{'serial'} = $x509->serial();
# Convert URNs to objects.
$self->{'CERT'}->{'urnOBJ'} = GeniHRN->new($urn);
......@@ -1087,6 +1094,59 @@ sub SubjectHash($)
return undef;
}
#
# We load these when requested, which is not often.
#
sub startdate($)
{
my ($self) = @_;
if (!defined($self->{'CERT'}->{'startdate'})) {
$self->LoadAdditionalStuff();
}
return $self->{'CERT'}->{'startdate'};
}
sub enddate($)
{
my ($self) = @_;
if (!defined($self->{'CERT'}->{'enddate'})) {
$self->LoadAdditionalStuff();
}
return $self->{'CERT'}->{'enddate'};
}
sub serial($)
{
my ($self) = @_;
if (!defined($self->{'CERT'}->{'serial'})) {
$self->LoadAdditionalStuff();
}
return $self->{'CERT'}->{'serial'};
}
sub LoadAdditionalStuff($)
{
my ($self) = @_;
my @result = $self->PipeTo(0, "$OPENSSL x509 -dates -serial -noout", 0);
if (! @result) {
print STDERR "Could not convert $self to dates and serial\n";
return -1;
}
foreach my $line (@result) {
if ($line =~ /^serial=(\w*)$/) {
$self->{'CERT'}->{'serial'} = $1;
}
elsif ($line =~ /^notBefore=(.*)$/) {
$self->{'CERT'}->{'startdate'} = TBDateStringGMT($1);
}
elsif ($line =~ /^notAfter=(.*)$/) {
$self->{'CERT'}->{'enddate'} = TBDateStringGMT($1);
}
}
return 0;
}
sub CommonName($)
{
my ($self) = @_;
......@@ -1441,6 +1501,41 @@ sub VerifyGeniChain($$@)
return 0;
}
#
# Split up a bundle and return list of certs.
#
sub SplitCertBundle($)
{
my ($filename) = @_;
my @certs = ();
my $certstr;
if (open(BUNDLE, $filename)) {
while (<BUNDLE>) {
if ($_ =~ /^-----BEGIN CERT/) {
$certstr = $_;
next;
}
if ($_ =~ /^-----END CERT/) {
$certstr .= $_;
push(@certs, $certstr);
$certstr = undef;
next;
}
if ($certstr) {
$certstr .= $_;
next;
}
}
# If the file is properly terminated, there should be no certificate in
# progress. Hopefully the file is not trashed at a boundry.
fatal("Trashed bundle file: $filename")
if ($certstr);
close(BUNDLE);
}
return @certs;
}
############################################################################
#
# Wrapper for local users.
......
#!/usr/bin/perl -w
#
# Copyright (c) 2011-2013 University of Utah and the Flux Group.
# Copyright (c) 2011-2016 University of Utah and the Flux Group.
#
# {{{GENIPUBLIC-LICENSE
#
......@@ -61,7 +61,6 @@ delete @ENV{'IFS', 'CDPATH', 'ENV', 'BASH_ENV'};
# Protos
sub fatal($);
sub SplitCertBundle($);
#
# Turn off line buffering on output
......@@ -82,6 +81,7 @@ if ($TB ne "/usr/testbed") {
use lib '@prefix@/lib';
use libaudit;
use GeniCertificate;
# For error log.
my $errors = 0;
......@@ -130,9 +130,10 @@ system("/bin/mv -f /tmp/wwwbundle.$$ $WWWBUNDLE") == 0
#
# Split up the extra certs.
#
my @certs = SplitCertBundle("$TB/etc/extracerts.bundle");
my @certs = GeniCertificate::SplitCertBundle("$TB/etc/extracerts.bundle");
if (-s "$TB/etc/unapproved.bundle") {
@certs = (@certs, SplitCertBundle("$TB/etc/unapproved.bundle"));
@certs = (@certs,
GeniCertificate::SplitCertBundle("$TB/etc/unapproved.bundle"));
}
mkdir("/tmp/extracerts.$$", 0755) or
......@@ -175,38 +176,3 @@ sub fatal($)
" $msg\n");
}
#
# Split up a bundle and return list of certs.
#
sub SplitCertBundle($)
{
my ($filename) = @_;
my @certs = ();
my $certstr;
if (open(BUNDLE, $filename)) {
while (<BUNDLE>) {
if ($_ =~ /^-----BEGIN CERT/) {
$certstr = $_;
next;
}
if ($_ =~ /^-----END CERT/) {
$certstr .= $_;
push(@certs, $certstr);
$certstr = undef;
next;
}
if ($certstr) {
$certstr .= $_;
next;
}
}
# If the file is properly terminated, there should be no certificate in
# progress. Hopefully the file is not trashed at a boundry.
fatal("Trashed bundle file: $filename")
if ($certstr);
close(BUNDLE);
}
return @certs;
}
#!/usr/bin/perl -w
#
# Copyright (c) 2008-2013 University of Utah and the Flux Group.
# Copyright (c) 2008-2016 University of Utah and the Flux Group.
#
# {{{GENIPUBLIC-LICENSE
#
......@@ -79,6 +79,7 @@ use libdb;
use libtestbed;
use libaudit;
use libEmulab;
use GeniCertificate;
if ($UID != 0) {
fatal("Must be root to run this script\n");
......@@ -154,41 +155,13 @@ system( "/bin/cat $TB/etc/extracerts.bundle >> /tmp/genica.bundle.$$ " .
#
# Split up the certs.
#
my @certs = ();
my $certstr;
open(BUNDLE, "/tmp/genica.bundle.$$")
or fatal("Could not open /tmp/genica.bundle.$$ for reading");
while (<BUNDLE>) {
if ($_ =~ /^-----BEGIN CERT/) {
$certstr = $_;
next;
}
if ($_ =~ /^-----END CERT/) {
$certstr .= $_;
push(@certs, $certstr);
$certstr = undef;
next;
}
if ($certstr) {
$certstr .= $_;
next;
}
}
#
# If the file is properly terminated, there should be no certificate in
# progress. Hopefully the file is not trashed at a boundry. We do this
# before the diff to make sure the file is reasonable.
#
fatal("Trashed bundle file")
if ($certstr);
close(BUNDLE);
my @certs = GeniCertificate::SplitCertBundle("/tmp/genica.bundle.$$");
#
# Go no further if the file is exactly the same as last time.
#
system("/usr/bin/diff -q $TB/etc/genica.bundle /tmp/genica.bundle.$$");
if ($?) {
if ($? || $force) {
my $idx = 0;
while (@certs) {
my $cert = pop(@certs);
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment