~pi-rho/+junk/cake

« back to all changes in this revision

Viewing changes to cake

  • Committer: pi-rho
  • Date: 2014-07-19 17:51:43 UTC
  • Revision ID: ubuntu@tyr.cx-20140719175143-2c2qvuv3z633iq4q
--sign changes
   more handling of subjectaltnames
   prompt user after displaying foreign CSR and a summary of parsed data to
   guard against rogue CSRs

Certificate Display changes:
  filter pubkey output in certificate and CSR outputs so that the
  size and type of public key is visible. Doesn't change the output
  of openssl ca when certificate is issued.

Show diffs side-by-side

added added

removed removed

Lines of Context:
163
163
        '[+]' => "\e[1;30m[\e[1;32m+\e[1;30m]\e[0m",
164
164
        '[!]' => "\e[1;30m[\e[1;33m+\e[1;30m]\e[0m",
165
165
        '[|]' => "\e[1;30m[\e[1;34m|\e[1;30m]\e[0m",
 
166
        '[?]' => "\e[1;30m[\e[1;35m?\e[1;30m]\e[0m",
166
167
        'Yes' => "\e[1;32mYes\e[0m",
167
168
        'OK'  => "\e[1;32mOK\e[0m",
168
169
        'No' => "\e[1;31mNo\e[0m",
181
182
    my $filter = 1;
182
183
    $opts{error} //= 0;
183
184
    $opts{verbose} //= 0;
 
185
    $opts{le} //= "\n";
184
186
    $filter += $opts{error} * $ERRWEIGHT;
185
187
    $filter -= $OPTIONS{quiet} * $QUIETWEIGHT if $OPTIONS{quiet};
186
188
    $filter -= $opts{verbose};
187
189
    $filter += $OPTIONS{verbose} if $OPTIONS{verbose};
188
190
 
189
191
    print colorize("[x] DEBUG: \$filter = $filter\n") if $OPTIONS{debug};
190
 
    return print colorize("[$marker] $message\n")
 
192
    return print colorize("[$marker] $message$opts{le}")
191
193
        if $filter > 0;
192
194
    return;
193
195
}
224
226
    exit $exitval;
225
227
}
226
228
 
 
229
# filter openssl's pubkey dump
 
230
sub pkfilter {
 
231
    my ($dump) = @_;
 
232
    $dump =~ s!
 
233
        \A(?<type>.*?):.*?
 
234
        ^(?<top>\s*Version:.*?)
 
235
        ^(?<pksp>\s*)(?:Modulus|pub):.*?
 
236
        ^\g{pksp}\s{4}
 
237
            [[:xdigit:]:\s]{12,}\s* $ \s* # pubkey dump
 
238
        ^(?<bot>.*)
 
239
    !$+{type} Data:\n$+{top}$+{bot}!smx;
 
240
    $dump =~ s/^ \s*$ .//gsmx;             # kill blank lines
 
241
    $dump =~ s/^\s{4}(\s+)/$1/gsmx;       # outdent the whole thing
 
242
    return $dump;
 
243
}
 
244
 
 
245
# prompt($msg, $accept_regex)
 
246
# Write a prompt, get input from the user
 
247
sub prompt {
 
248
    my ($msg, $accept) = @_;
 
249
    _output(q{?}, "$msg ", le => '');
 
250
    my $inp = <STDIN>; chomp $inp;
 
251
    return $inp =~ $accept;
 
252
}
 
253
 
227
254
# End Output Functions }}}
228
255
# OpenSSL Functions -- {{{
229
256
 
559
586
    return \%dn;
560
587
}
561
588
 
 
589
# $sanref = getaltnames("request.csr")
 
590
# create altnames from a CSR
 
591
sub getaltnames {
 
592
    my ($fn) = @_;
 
593
    my @altnames = ();
 
594
    my $reqtext = openssl("req -text -noout -reqopt no_pubkey,no_sigdump -in '$fn'", 1);
 
595
    return unless $reqtext =~ m/X509v3 Subject Alternative Name:/;
 
596
 
 
597
    if ($reqtext =~ m{^\s*X509v3\sSubject\sAlternative\sName:\s*(.*?)\s*$}smx) {
 
598
        @altnames = map { my $s=$_; $s =~ s/IP Address/IP/; $s } split /, /, $1;
 
599
    } else {
 
600
        @altnames = undef;
 
601
    }
 
602
    return \@altnames;
 
603
}
 
604
 
562
605
# $dnref = getdn("request.csr")
563
606
# create a DN from a CSR
564
607
sub getdn {
1164
1207
    $arg = findtypes($arg) unless -f $arg;
1165
1208
 
1166
1209
    output("SHOW: Found $arg:");
1167
 
    openssl("x509 -text -certopt no_sigdump,no_pubkey -noout -in '$arg'");
 
1210
    cmdoutput(pkfilter(openssl("x509 -text -certopt no_sigdump,ext_parse -noout -in '$arg'", 1)));
1168
1211
    return;
1169
1212
}
1170
1213
 
1294
1337
            badusage("CSR $fn not found")
1295
1338
                unless -f $fn;
1296
1339
 
 
1340
            my $dn = getdn($fn);
 
1341
            $OPTIONS{altname} //= getaltnames($fn);
 
1342
 
 
1343
            output("SIGN: Foreign Certificate Signing Request");
 
1344
            cmdoutput(pkfilter(openssl("req -text -noout -reqopt no_sigdump,ext_parse -in '$fn'", 1)));
 
1345
            output("SIGN: Parsed DirName: ". dnarg($dn));
 
1346
            output("SIGN: Parsed AltName: ". join(', ', @{ $OPTIONS{altname} }));
 
1347
            output(sprintf "SIGN: Will be signed as %s for %d days using %s signature algorithm.", $type, $OPTIONS{days}, $OPTIONS{md});
 
1348
            return 1 unless prompt("SIGN: Are you sure that you want to issue the requested certificate?", qr/^Y(es)?$/i);
 
1349
 
1297
1350
            # Build the certificate config
1298
1351
            return gencert(request => {
1299
 
                DN         => getdn($fn),
 
1352
                DN         => $dn,
1300
1353
                type       => $type,
1301
1354
                keylen     => $OPTIONS{keylen},
1302
1355
                altname    => sanstring(mksanhash($OPTIONS{altname})),