From 38b341d270ff8052068a44cbe5c3c5fa783b67c9 Mon Sep 17 00:00:00 2001 From: Ian Young Date: Fri, 28 Aug 2009 17:06:40 +0000 Subject: [PATCH] Allow DNS subjectAlternativeNames to match against the KeyName in metadata. Fixes http://bugzilla.iay.org.uk/show_bug.cgi?id=690 --- build/check_embedded.pl | 49 +++++++++++++++++++++++++++++++++++++++-- 1 file changed, 47 insertions(+), 2 deletions(-) diff --git a/build/check_embedded.pl b/build/check_embedded.pl index 65b766d2..a401e28e 100755 --- a/build/check_embedded.pl +++ b/build/check_embedded.pl @@ -115,6 +115,11 @@ sub comment { # as input, perhaps multiple times. # + # + # Collection of names this certificate contains + # + my %names; + # # Use openssl to convert the certificate to text # @@ -123,6 +128,7 @@ sub comment { open(SSL, $cmd) || die "could not open openssl subcommand"; while () { push @lines, $_; + if (/^\s*Issuer:\s*(.*)$/) { $issuer = $1; if ($issuer =~ /CN=([^,]+)/) { @@ -130,18 +136,25 @@ sub comment { } else { $issuerCN = $issuer; } + next; } + if (/^\s*Subject:\s*.*?CN=([a-z0-9\-\.]+).*$/) { $subjectCN = $1; + $names{$subjectCN}++; # print "subjectCN = $subjectCN\n"; + next; } + if (/RSA Public Key: \((\d+) bit\)/) { $pubSize = $1; # print " Public key size: $pubSize\n"; if ($pubSize < 1024) { error('PUBLIC KEY TOO SHORT'); } + next; } + if (/Not After : (.*)$/) { $notAfter = $1; $days = (str2time($notAfter)-time())/86400.0; @@ -154,6 +167,7 @@ sub comment { $days = int($days); warning("expires in $days days"); } + next; } # @@ -176,6 +190,36 @@ sub comment { error("WEAK DEBIAN KEY"); } } + next; + } + + # + # subjectAlternativeName + # + if (/X509v3 Subject Alternative Name:/) { + # + # Steal the next line, which will look like this: + # + # DNS:www.example.co.uk, DNS:example.co.uk, URI:http://example.co.uk/ + # + my $next = ; + + # + # Make an array of components, each something like "DNS:example.co.uk" + # + $next =~ s/\s*//g; + my @altNames = split /\s*,\s*/, $next; + # my $altSet = "{" . join(", ", @altNames) . "}"; + # print "Alt set: $altSet\n"; + + # + # Each "DNS" component is an additional name for this certificate. + # + while (@altNames) { + my ($type, $altName) = split(":", pop @altNames); + $names{$altName}++ if $type eq 'DNS'; + } + next; } } @@ -185,8 +229,9 @@ sub comment { # # Check KeyName if one has been supplied. # - if ($hasKeyName && $keyname ne $subjectCN) { - error("KeyName mismatch: $keyname != $subjectCN"); + if ($hasKeyName && !defined($names{$keyname})) { + my $nameList = join ", ", sort keys %names; + error("KeyName mismatch: $keyname not in {$nameList}"); } #