bin/sslcert
changeset 1 633e40534da4
parent 0 71dcb82a1b31
child 2 109f9cc18906
equal deleted inserted replaced
0:71dcb82a1b31 1:633e40534da4
       
     1 #!/usr/bin/perl
       
     2 
       
     3 use 5.010;
       
     4 use strict;
       
     5 use warnings;
       
     6 
       
     7 use if $ENV{DEBUG} => "Smart::Comments";
       
     8 my $pfad = "./CA";
       
     9 
       
    10 
       
    11 sub menue() {
       
    12     my $eg = "";
       
    13 
       
    14     while (1) {
       
    15 	system("clear");
       
    16         print
       
    17 " Willkommen beim SSL-Certificator, Ihrem nuetzlichem Perlprogramm\n zum einfachen erstellen von SSL-Zertifikaten.\n\n\n";
       
    18         print " Menue\n\n";
       
    19         print
       
    20 "  n - Neues Root-Zertifikat erstellen\n  r - Request erstellen\n  s - Request signieren\n  w - Zertifikat wiederrufen\n  a - Annulierungsliste erstellen\n\n  q - Beenden\n\n ";
       
    21         chomp($eg = <STDIN>);
       
    22 
       
    23 	given ($eg) {
       
    24 	    when("q") {	# $eg ~~ "q"
       
    25 		system('clear');
       
    26 		exit;
       
    27 	    }
       
    28 	    when("n") {
       
    29 		system('clear');
       
    30 		&rootca;
       
    31 	    }
       
    32 	    default {
       
    33 	    }
       
    34 	}
       
    35 
       
    36 #	SWITCH: {
       
    37 #	    ($eg eq "q") and do { ….; last SWITCH; }
       
    38 #	    ($eq eq "n") and do { …; last SWITCH; }
       
    39 #	}
       
    40 
       
    41 #        } elsif ($eg eq 's') {
       
    42 #            system('clear');
       
    43 #            &sign;
       
    44 #        } elsif ($eg eq 'r') {
       
    45 #            system('clear');
       
    46 #            &request;
       
    47 #        }
       
    48 #        if ($eg eq 'w') {
       
    49 #            system('clear');
       
    50 #            &revoke;
       
    51 #        }
       
    52 #        if ($eg eq 'a') {
       
    53 #            system('clear');
       
    54 #            &revlist;
       
    55 #        }
       
    56       }
       
    57 }
       
    58 
       
    59 sub rootca {
       
    60     my $days;
       
    61     my $pk;
       
    62     my $rca;
       
    63     print " Ihr Zertifikat wird erstellt. Bitte warten Sie.\n";
       
    64     print " ...\n ";
       
    65 
       
    66     mkdir($_ = "$pfad/newcerts") or die "Can't mkdir $_: $!\n";
       
    67 
       
    68     system("mkdir -p $pfad/newcerts");	# mkdir / File::Path::make_path
       
    69     system("mkdir -p $pfad/private");
       
    70 
       
    71     # system("echo '01' >$pfad/serial");
       
    72     {
       
    73 	open(my $x, ">", "$pfad/serial") or die;
       
    74 	print $x "01\n";
       
    75 	close($x);
       
    76     }
       
    77 
       
    78     #if (-e "$pfad/index.txt") {		    # RACE CONDITION
       
    79     #    system("/bin/rm $pfad/index.txt");	    # rm -f
       
    80     #}
       
    81 #    unlink "$pfad/index.txt";
       
    82 #    system("/bin/touch $pfad/index.txt");
       
    83     {
       
    84 	open(my $x, ">", "$pfad/index.txt");
       
    85 	close($x);
       
    86     }
       
    87     open(CONF, ">$pfad/openssl.cnf");
       
    88     print CONF
       
    89 "#\n# OpenSSL configuration file.\n#\n\n# Establish working directory.\n\ndir = $pfad\n\n[ req ]\ndefault_bits\t\t= 1024\t\t# Size of keys\ndefault_keyfile\t\t= key.pem\t\t# name of generated keys\ndefault_md\t\t= md5\t\t# message digest algorithm\nstring_mask\t\t= nombstr\t\t# permitted characters\ndistinguished_name\t= req_distinguished_name\n\n[ req_distinguished_name ]\n# Variable name\t\t\t  Prompt string\n#----------------------\t  ----------------------------------\n0.organizationName\t= Organization Name (company)\norganizationalUnitName\t= Organizational Unit Name (department, division)\nemailAddress\t\t= Email Address\nemailAddress_max\t= 40\nlocalityName\t\t= Locality Name (city, district)\nstateOrProvinceName\t= State or Province Name (full name)\ncountryName\t\t= Country Name (2 letter code)\ncountryName_min\t\t= 2\ncountryName_max\t\t= 2\ncommonName\t\t= Common Name (hostname, IP, or your name)\ncommonName_max\t\t= 64\n\n# Default values for the above, for consistency and less typing.\n# Variable name\t\t\t  Value\n#------------------------------\t  ------------------------------\n0.organizationName_default\t= Your Company\nlocalityName_default\t\t= Your City\nstateOrProvinceName_default\t= Your Province\ncountryName_default\t\t= OO\n\n[ v3_ca ]\nbasicConstraints\t= CA:TRUE\nsubjectKeyIdentifier\t= hash\nauthorityKeyIdentifier\t= keyid:always,issuer:always";
       
    90     print CONF <<_EOT;
       
    91 127.0.0.1	localhost 
       
    92 127.0.1.1	jumper.schlittermann.de	jumper
       
    93 212.80.235.130  pu.schlittermann.de ssl.schlittermann.de pu
       
    94 
       
    95 # The following lines are desirable for IPv6 capable hosts
       
    96 ::1     ip6-localhost ip6-loopback
       
    97 fe00::0 ip6-localnet
       
    98 ff00::0 ip6-mcastprefix
       
    99 ff02::1 ip6-allnodes
       
   100 ff02::2 ip6-allrouters
       
   101 _EOT
       
   102 
       
   103     close CONF;
       
   104     <STDIN>;
       
   105     do {
       
   106         system('clear');
       
   107         print
       
   108           " Wie lange soll das Zertifikat gueltig sein? (Angabe in Tagen)\n ";
       
   109         chomp($days = <STDIN>);
       
   110     } while ($days !~ m/\d*/);
       
   111     system('clear');
       
   112     print " Ihr Zertifikat wird $days Tage gueltig sein.\n ";
       
   113     system(
       
   114 "/usr/bin/openssl req -new -x509 -extensions v3_ca -keyout $pfad/private/cakey.pem -out $pfad/cacert.pem -days $days -config $pfad/openssl.cnf"
       
   115     );
       
   116     <STDIN>;
       
   117     do {
       
   118         system('clear');
       
   119         print
       
   120 " Moechten Sie sich den Private Key ansehen?\n\n  j - ja\n  n - nein\n\n ";
       
   121         chomp($pk = <STDIN>);
       
   122         system('clear');
       
   123         if ($pk eq 'j') {
       
   124             system("/bin/cat $pfad/private/cakey.pem");
       
   125             <STDIN>;
       
   126         }
       
   127     } until ($pk ne 'j' | $pk ne 'n');
       
   128     do {
       
   129         system('clear');
       
   130         print
       
   131 " Moechten Sie sich das Zertifikat ansehen?\n\n  j - ja\n  n - nein\n\n ";
       
   132         chomp($rca = <STDIN>);
       
   133         system('clear');
       
   134         if ($rca eq 'j') {
       
   135             system("/bin/cat $pfad/cacert.pem");
       
   136             <STDIN>;
       
   137         }
       
   138     } until ($rca ne 'j' | $rca ne 'n');
       
   139     system('clear');
       
   140     &menue;
       
   141 }
       
   142 
       
   143 sub request {
       
   144     my $egreq;
       
   145     my $rootpf;
       
   146     my $config;
       
   147     my $eg;
       
   148     do {
       
   149         system('clear');
       
   150         print
       
   151 " Konfigurationsdatei erstellen oder Pfad angeben?\n\n  e - erstellen\n  p - Pfad angeben\n\n ";
       
   152         chomp($eg = <STDIN>);
       
   153         system('clear');
       
   154     } until ($eg ne 'e' | $eg ne 'p');
       
   155     if ($eg eq 'e') {
       
   156         if (-d $pfad) {
       
   157             open(CONF, ">$pfad/openssl.cnf");
       
   158             print CONF
       
   159 "#\n# OpenSSL configuration file.\n#\n\n# Establish working directory.\n\ndir = $pfad\n\n[ req ]\ndefault_bits\t\t= 1024\t\t# Size of keys\ndefault_keyfile\t\t= key.pem\t\t# name of generated keys\ndefault_md\t\t= md5\t\t# message digest algorithm\nstring_mask\t\t= nombstr\t\t# permitted characters\ndistinguished_name\t= req_distinguished_name\nreq_extensions\t\t= v3_req\n\n[ req_distinguished_name ]\n# Variable name\t\t\t  Prompt string\n#----------------------\t  ----------------------------------\n0.organizationName\t= Organization Name (company)\norganizationalUnitName\t= Organizational Unit Name (department, division)\nemailAddress\t\t= Email Address\nemailAddress_max\t= 40\nlocalityName\t\t= Locality Name (city, district)\nstateOrProvinceName\t= State or Province Name (full name)\ncountryName\t\t= Country Name (2 letter code)\ncountryName_min\t\t= 2\ncountryName_max\t\t= 2\ncommonName\t\t= Common Name (hostname, IP, or your name)\ncommonName_max\t\t= 64\n\n# Default values for the above, for consistency and less typing.\n# Variable name\t\t\t  Value\n#------------------------------\t  ------------------------------\n0.organizationName_default\t= Your Company\nlocalityName_default\t\t= Your City\nstateOrProvinceName_default\t= Your Province\ncountryName_default\t\t= OO\n\n[ v3_ca ]\nbasicConstraints\t\t= CA:TRUE\nsubjectKeyIdentifier\t\t= hash\nauthorityKeyIdentifier\t\t= keyid:always,issuer:always\n\n[ v3_req ]\nbasicConstraints\t\t= CA:FALSE\nsubjectKeyIdentifier\t\t= hash";
       
   160             close CONF;
       
   161         }
       
   162         else {
       
   163             system("/bin/mkdir $pfad");
       
   164             open(CONF, ">$pfad/openssl.cnf");
       
   165             print CONF
       
   166 "#\n# OpenSSL configuration file.\n#\n\n# Establish working directory.\n\ndir = $pfad\n\n[ req ]\ndefault_bits\t\t= 1024\t\t# Size of keys\ndefault_keyfile\t\t= key.pem\t\t# name of generated keys\ndefault_md\t\t= md5\t\t# message digest algorithm\nstring_mask\t\t= nombstr\t\t# permitted characters\ndistinguished_name\t= req_distinguished_name\nreq_extensions\t\t= v3_req\n\n[ req_distinguished_name ]\n# Variable name\t\t\t  Prompt string\n#----------------------\t  ----------------------------------\n0.organizationName\t= Organization Name (company)\norganizationalUnitName\t= Organizational Unit Name (department, division)\nemailAddress\t\t= Email Address\nemailAddress_max\t= 40\nlocalityName\t\t= Locality Name (city, district)\nstateOrProvinceName\t= State or Province Name (full name)\ncountryName\t\t= Country Name (2 letter code)\ncountryName_min\t\t= 2\ncountryName_max\t\t= 2\ncommonName\t\t= Common Name (hostname, IP, or your name)\ncommonName_max\t\t= 64\n\n# Default values for the above, for consistency and less typing.\n# Variable name\t\t\t  Value\n#------------------------------\t  ------------------------------\n0.organizationName_default\t= Your Company\nlocalityName_default\t\t= Your City\nstateOrProvinceName_default\t= Your Province\ncountryName_default\t\t= OO\n\n[ v3_ca ]\nbasicConstraints\t\t= CA:TRUE\nsubjectKeyIdentifier\t\t= hash\nauthorityKeyIdentifier\t\t= keyid:always,issuer:always\n\n[ v3_req ]\nbasicConstraints\t\t= CA:FALSE\nsubjectKeyIdentifier\t\t= hash";
       
   167             close CONF;
       
   168         }
       
   169         print " Konfigurationsdatei erstellt $pfad/openssl.cnf\n ";
       
   170         <STDIN>;
       
   171     }
       
   172     if ($eg eq 'p') {
       
   173         system('clear');
       
   174         print " Bitte geben Sie den Pfad zu Ihrer Konfigurationsdatei an.\n ";
       
   175         chomp($config = <STDIN>);
       
   176         system('clear');
       
   177         print
       
   178 " Bitte achten Sie darauf, dass sie den Common Name aendern, sodass er zu Ihrer Domain passt.\n Bsp.:\n\n Domain: hostname.domainname\n         secure.yourdomain.de\n\n ";
       
   179 	system("openssl", $pfad)
       
   180         system(openssl => qw(req -new -nodes),  
       
   181 	    -out => "$pfad/req.pem", 
       
   182 	    -config => $config);
       
   183     }
       
   184     else {
       
   185         system('clear');
       
   186         print
       
   187 " Bitte achten Sie darauf, dass sie den Common Name aendern, sodass er zu Ihrer Domain passt.\n Bsp.:\n\n Domain: hostname.domainname\n         secure.yourdomain.de ";
       
   188         system(
       
   189 "/usr/bin/openssl req -new -nodes -out $pfad/req.pem -config $pfad/openssl.cnf"
       
   190         );
       
   191     }
       
   192     <STDIN>;
       
   193     do {
       
   194         system('clear');
       
   195         print " Request ueberpruefen?\n\n  j - ja\n  n - nein\n\n ";
       
   196         chomp($egreq = <STDIN>);
       
   197         if ($egreq eq 'j') {
       
   198             system('clear');
       
   199             system(
       
   200                 "/usr/bin/openssl req -in $pfad/req.pem -text -verify -noout");
       
   201             <STDIN>;
       
   202         }
       
   203     } until ($egreq ne 'j' | $egreq ne 'n');
       
   204     system('clear');
       
   205     &menue;
       
   206 }
       
   207 
       
   208 sub sign {
       
   209     my $eg;
       
   210     open(CONF, ">$pfad/openssl.cnf");
       
   211     print CONF
       
   212 "#\n# OpenSSL configuration file.\n#\n\n# Establish working directory.\n\ndir = $pfad\n\n[ ca ]\ndefault_ca\t\t= CA_default\n\n[ CA_default ]\nserial\t\t\t= \$dir/serial\ndatabase\t\t= \$dir/index.txt\nnew_certs_dir\t\t= \$dir/newcerts\ncertificate\t\t= \$dir/cacert.pem\nprivate_key\t\t= \$dir/private/cakey.pem\ndefault_days\t\t= 365\ndefault_md\t\t= md5\npreserve\t\t= no\nemail_in_dn\t\t= no\nnameopt\t\t\t= default_ca\ncertopt\t\t\t= default_ca\npolicy\t\t\t= policy_match\n\n[ policy_match ]\ncountryName\t\t= match\nstateOrProvinceName\t= match\norganizationName\t= match\norganizationalUnitName\t= optional\ncommonName\t\t= supplied\nemailAddress\t\t= optional\n\n[ req ]\ndefault_bits\t\t= 1024\t\t# Size of keys\ndefault_keyfile\t\t= key.pem\t\t# name of generated keys\ndefault_md\t\t= md5\t\t# message digest algorithm\nstring_mask\t\t= nombstr\t\t# permitted characters\ndistinguished_name\t= req_distinguished_name\nreq_extensions\t\t= v3_req\n\n[ req_distinguished_name ]\n# Variable name\t\t\t  Prompt string\n#----------------------\t  ----------------------------------\n0.organizationName\t= Organization Name (company)\norganizationalUnitName\t= Organizational Unit Name (department, division)\nemailAddress\t\t= Email Address\nemailAddress_max\t= 40\nlocalityName\t\t= Locality Name (city, district)\nstateOrProvinceName\t= State or Province Name (full name)\ncountryName\t\t= Country Name (2 letter code)\ncountryName_min\t\t= 2\ncountryName_max\t\t= 2\ncommonName\t\t= Common Name (hostname, IP, or your name)\ncommonName_max\t\t= 64\n\n# Default values for the above, for consistency and less typing.\n# Variable name\t\t\t  Value\n#------------------------------\t  ------------------------------\n0.organizationName_default\t= Your Company\nlocalityName_default\t\t= Your City\nstateOrProvinceName_default\t= Your Province\ncountryName_default\t\t= OO\n\n[ v3_ca ]\nbasicConstraints\t\t= CA:TRUE\nsubjectKeyIdentifier\t\t= hash\nauthorityKeyIdentifier\t\t= keyid:always,issuer:always\n[ v3_req ]\nbasicConstraints\t\t= CA:FALSE\nsubjectKeyIdentifier\t\t= hash";
       
   213     system(
       
   214 "/usr/bin/openssl ca -out $pfad/cert.pem -config $pfad/openssl.cnf -infiles $pfad/req.pem"
       
   215     );
       
   216     print "Zertifikat wurde unterzeichnet";
       
   217     <STDIN>;
       
   218     do {
       
   219         system('clear');
       
   220         print "Zertifikat ueberpruefen?\n\n  j - ja\n  n - nein\n\n";
       
   221         chomp($eg = <STDIN>);
       
   222         if ($eg eq 'j') {
       
   223             system(
       
   224 "/usr/bin/openssl x509 -in $pfad/cert.pem -noout -text -purpose | /bin/more"
       
   225             );
       
   226             <STDIN>;
       
   227         }
       
   228     } until ($eg ne 'j' | $eg ne 'n');
       
   229     $eg = '';
       
   230     do {
       
   231         system('clear');
       
   232         print
       
   233 "Sollen die lesbaren Elemente aus dem Zertifikat entfernt werden?\n\n  j - ja\n  n - nein\n\n";
       
   234         chomp($eg = <STDIN>);
       
   235         if ($eg eq 'j') {
       
   236             print "...\n";
       
   237 	    # rename()
       
   238 	    # File::Copy
       
   239             system("/bin/mv $pfad/cert.pem $pfad/tmp.pem");
       
   240             system(
       
   241                 "/usr/bin/openssl x509 -in $pfad/tmp.pem -out $pfad/cert.pem");
       
   242             print "Alle lesbaren Elemente wurden entfernt.";
       
   243             <STDIN>;
       
   244         }
       
   245     } until ($eg ne 'j' | $eg ne 'n');
       
   246     &menue;
       
   247 }
       
   248 
       
   249 sub revoke {
       
   250     my $eg;
       
   251     do {
       
   252         print
       
   253 "Welches Zertifikat soll wiederrufen werden?\nFuer Informationen zu allen Zertifikaten, schauen\nSie in die Datei index.txt.\n";
       
   254         print "Datei öffnen?\n\nj - ja\nn - nein\n\n";
       
   255         chomp($eg = <STDIN>);
       
   256         if ($eg eq 'j') {
       
   257             open(INDEX, "<$pfad/index.txt");
       
   258             my @index = <INDEX>;
       
   259             print sort @index;
       
   260             <STDIN>;
       
   261         }
       
   262     } until ($eg eq 'j' | $eg eq 'n');
       
   263     print
       
   264 "Welches Zertifikat soll wiederrufen werden?\n(Geben Sie die 2-stellige Nummer ein)\n";
       
   265     chomp($eg = <STDIN>);
       
   266     system(
       
   267 "/usr/bin/openssl ca -revoke $pfad/newcerts/$eg.pem -config $pfad/openssl.cnf"
       
   268     );
       
   269     print "Zertifikat $eg wiederrufen.";
       
   270     <STDIN>;
       
   271     &menue;
       
   272 }
       
   273 
       
   274 sub revlist {
       
   275     system(
       
   276 "/usr/bin/openssl ca -gencrl -crldays 31 -config $pfad/openssl.cnf -out $pfad/rootca.crl"
       
   277     );
       
   278     print "Certicate Revocation List erstellt";
       
   279     <STDIN>;
       
   280     &menue;
       
   281 }
       
   282 
       
   283 sub main(@) {
       
   284     menue();
       
   285     exit 0;
       
   286 }
       
   287 
       
   288 main(@ARGV);