Request a certificate using a PHP script
Our certification servers accept certification requests not only via WWW but also via a SOAP interface.
The PHP script below generates a new key pair and a certification request for a TLS server and uses this interface to submit the request to the certification server and to download the PDF file that has to be printed, signed, and handed over to the participant service of the CA.
The script is deliberately kept simple so that everybody with sufficient knowledge of PHP can adopt it to his needs, even when using Windows or Macintosh computers.
#!/usr/bin/php <?php # adopt the following data for each certificate request: # "Permitted" characters are: # A-Z a-z 0-9 ' ( ) + , - . / : = ? # and the space character, but no umlauts # Name of applicant (permitted characters only) $name = 'Rainer Perske'; # email address of applicant $mail = 'wwwadmin@uni-muenster.de'; # organizational unit of applicant (permitted characters only) $unit = 'IT'; # path and name of the file with the applicant's PIN code # (for each request, another PIN may be chosen) $code = '/path/to/file/with/the/pin'; # RA-ID of the responsible participant service staff member # 4930=university # 5540=academy of fine arts $raid = 4930; # requested certificate profile # for modern TLS servers choose 'Webserver MustStaple' # (modern TLS servers support OCSP Stapling) # for old TLS servers choose 'Web Server' # for TLS servers and clients choose 'Mail Server' # please get advice from the CA when needed $profil = 'Webserver MustStaple'; # main fully qualified domain name of the server $fqdn = 'hostname.uni-muenster.de'; # requested distinguished name of the server in OpenSSL format # possibly occurring "/" must be escaped with backslash $subject = '/C=DE' . '/ST=Nordrhein-Westfalen' . '/L=Muenster' . '/O=Westfaelische Wilhelms-Universitaet Muenster' . '/CN=' . strtr($fqdn, array( '/' => '\\/' )); # all Subject Alternative Names to be included into the certificate # the main name above must always be included $altnames = array( 'dns:' . $fqdn, 'dns:hostname2.uni-muenster.de', 'dns:hostname.wwu.de', 'dns:hostname2.wwu.de', ); # path and name of the file with the root certificates in PEM format # you can find the root certificates here: # https://www.uni-muenster.de/CA/all-rootca.pem $root = '/path/to/file/with/root/certificate'; # end of settings # generate key pair and request # (using the OpenSSL functions of PHP would be much more # complicated) passthru('/usr/bin/openssl req -new -sha256 -newkey rsa:2048 -nodes' . ' -keyout ' . escapeshellarg( "$fqdn.key" ) . ' -out ' . escapeshellarg( "$fqdn.req" ) . ' -subj ' . escapeshellarg( $subject ) ); # load request and PIN from the files $req = file_get_contents("$fqdn.req") or die("Error loading $fqdn.req\n"); $pin = file_get_contents($code) or die("Error loading $code\n"); # establish SOAP connection # the details with (P) are necessary only if access to the # certification server must be made via the proxy server $soap = new SoapClient( 'https://pki.pca.dfn.de/dfn-ca-global-g2/cgi-bin/pub/soap?wsdl=1', array( 'trace' => false, 'exceptions' => false, 'features' => SOAP_SINGLE_ELEMENT_ARRAYS, 'cache_wsdl' => WSDL_CACHE_NONE, 'proxy_host' => 'wwwproxy.uni-muenster.de', # (P) 'proxy_port' => 3128, # (P) 'typemap' => array(), 'stream_context' => stream_context_create(array( 'http' => array( 'proxy' => 'tcp://wwwproxy.uni-muenster.de:3128', # (P) 'request_fulluri' => true, # (P) 'timeout' => 60, ), 'ssl' => array( 'verify_peer' => true, 'cafile' => $root, 'verify_depth' => 3, # RootCA > DFN-PCA > CA > Server ), # or: RootCA > USERTrust CA > GÉANT TCS > Server )), ) ) or die("Error establishing the SOAP connection\n"); # submit request $soapdata = $soap->newRequest( $raid, # RA-ID $req, # Request in PEM format $altnames, # Array with the Subject Alternative Names $profil, # certification profile sha1($pin), # PIN $name, # name of applicant $mail, # email of applicant $unit, # organizational unit of applicant true # publish the certificate? ); if(is_soap_fault($soapdata)) die("Error submitting the request:\n" . "{$soapdata->faultcode}: {$soapdata->faultstring}\n"); if(!$soapdata) die("Error submitting the request\n"); $reqnum = intval($soapdata); # download PDF file $soapdata = $soap->getRequestPrintout( $raid, # RA-ID $reqnum, # request number, has been assigned above 'application/pdf', # no other setting allowed sha1($pin) # must be the same PIN as above ); if(is_soap_fault($soapdata)) die("Error downloading the PDF file:\n" . "{$soapdata->faultcode}: {$soapdata->faultstring}\n"); if(!$soapdata) die("Error downloading the PDF file\n"); # save the PDF file file_put_contents("$fqdn.pdf",$soapdata) or die("Error saving the PDF file to $fqdn.pdf\n"); # terminate SOAP connection unset($soap); ?>
This script creates these files:
- hostname.uni-muenster.de.key
the private key in PEM format (unprotected)
suitable for the Apache statement SSLCertificateKeyFile- hostname.uni-muenster.de.req
the uploaded certification request in PEM format
- hostname.uni-muenster.de.pdf
the PDF file
- hostname.uni-muenster.de.cert
the issued certificate from the email in PEM format
suitable for the Apache statement SSLCertificateFile- hostname.uni-muenster.de.chain
Intermediate CA certificates in PEM format
suitable for the Apache statement SSLCertificateChainFile
This PDF file must now be printed, signed, and handed over to a participant service staff member.
You will later receive the certificate by email. Then you should save the attachment into a file:
You should also save these certificates of the intermediate certification authorities:
The issued certificate can be fetched via SOAP, too. To do so, you have to combine large parts of the script above with the PHP fragment below:
# Download certificate $soapdata = $soap->getCertificateByRequestSerial( $raid, # RA-ID $reqnum, # request number, has been assigned above sha1($pin) # must be the same PIN as above ); if(is_soap_fault($soapdata)) die("Error downloading the certificate:\n" . "{$soapdata->faultcode}: {$soapdata->faultstring}\n"); if(!$soapdata) die("Error downloading the certificate\n"); # Save certificate file_put_contents("$fqdn.cert",$soapdata) or die("Error saving the certificate to $fqdn.cert\n");