From 1cac9a68bab207cab3fd3790baec4569a0acd385 Mon Sep 17 00:00:00 2001 From: Janne Anttila Date: Mon, 7 Sep 2009 12:48:18 +0300 Subject: Createpackage support for signing SIS with multiple certificates. This commit extends createpackage with capability to sign the SIS file with several certificates. The certificates need to be listed in text file. The file can have several certificates, each specified in separate line. The certificate, key and passphrase in line must be ';' separated. Lines starting with '#' are treated as a comments. Also empty lines in the file are ignored. The paths in certificate info file can be absolute or relative to the given file. Example syntax for certificateinfo file (mycerts.txt): # This is comment line, also the empty lines are ignored rd.cer;rd-key.pem .\cert\mycert.cer;.\cert\mykey.key;yourpassword X:\QtS60\selfsigned.cer;X:\QtS60\selfsigned.key To use this file the creatapackage has to be invokes as follows: createpackage.pl -c=mycerts.txt templatepkg release-armv5 Reviewed-by: Shane Kearns Reviewed-by: Miikka Heikkinen --- bin/createpackage.pl | 120 +++++++++++++++++++++++++++++++++++++++------------ 1 file changed, 93 insertions(+), 27 deletions(-) diff --git a/bin/createpackage.pl b/bin/createpackage.pl index 2e31544..1a83abb 100644 --- a/bin/createpackage.pl +++ b/bin/createpackage.pl @@ -52,42 +52,70 @@ use strict; use Getopt::Long; # Use file name parsing module use File::Basename; +# Use File::Spec services mainly rel2abs +use File::Spec; +# use CWD abs_bath, which is exported only on request +use Cwd 'abs_path'; + sub Usage() { - print "\n"; - print "==========================================================================================\n"; - print "Convenience script for creating signed packages you can install on your phone.\n"; - print "\n"; - print "Usage: createpackage.pl [-i] templatepkg target-platform [certificate key [passphrase]]\n"; - print "\n"; - print "Where parameters are as follows:\n"; - print " [-i|install] = Install the package right away using PC suite\n"; - print " [-p|preprocess] = Only preprocess the template .pkg file.\n"; - print " templatepkg = Name of .pkg file template\n"; - print " target = Either debug or release\n"; - print " platform = One of the supported platform\n"; - print " winscw | gcce | armv5 | armv6 | armv7\n"; - print " certificate = The certificate file used for signing\n"; - print " key = The certificate's private key file\n"; - print " passphrase = The certificate's private key file's passphrase\n"; - print "\n"; - print "For example:\n"; - print " createpackage.pl fluidlauncher_template.pkg release-armv5\n"; - print "\n"; - print "If no certificate and key files are provided, either a RnD certificate or\n"; - print "a self-signed certificate from Qt installation root directory is used.\n"; - print "\n"; - print "==========================================================================================\n"; + print <] = The file containing certificate information for signing. + The file can have several certificates, each specified in + separate line. The certificate, key and passphrase in line + must be ';' separated. Lines starting with '#' are treated + as a comments. Also empty lines are ignored. The paths in + can be absolute or relative to . +Where parameters are as follows: + templatepkg = Name of .pkg file template + target = Either debug or release + platform = One of the supported platform + winscw | gcce | armv5 | armv6 | armv7 + certificate = The certificate file used for signing + key = The certificate's private key file + passphrase = The certificate's private key file's passphrase + +Example: + createpackage.pl fluidlauncher_template.pkg release-armv5 + +Example with certfile: + createpackage.pl -c=mycerts.txt fluidlauncher_template.pkg release-armv5 + + Content of 'mycerts.txt' must be something like this: + # This is comment line, also the empty lines are ignored + rd.cer;rd-key.pem + .\\cert\\mycert.cer;.\\cert\\mykey.key;yourpassword + X:\\QtS60\\selfsigned.cer;X:\\QtS60\\selfsigned.key + +If no certificate and key files are provided, either a RnD certificate or +a self-signed certificate from Qt installation root directory is used. +============================================================================================== + +ENDUSAGESTRING + exit(); } # Read given options my $install = ""; my $preprocessonly = ""; -unless (GetOptions('i|install' => \$install, 'p|preprocess' => \$preprocessonly)){ +my $certfile = ""; + +unless (GetOptions('i|install' => \$install, 'p|preprocess' => \$preprocessonly, 'c|certfile=s' => \$certfile)){ Usage(); } +my $certfilepath = abs_path(dirname($certfile)); + # Read params to variables my $templatepkg = $ARGV[0]; my $targetplatform = lc $ARGV[1]; @@ -155,6 +183,32 @@ if (length($certificate)) { } } +# Read the certificates from file to two dimensional array +my @certificates; +if (length($certfile)) { + open CERTFILE, "<$certfile" or die $!; + while(){ + s/#.*//; # ignore comments by erasing them + next if /^(\s)*$/; # skip blank lines + chomp; # remove trailing newline characters + my @certinfo = split(';', $_); # split row to certinfo + + # Trim spaces + for(@certinfo) { + s/^\s+//; + s/\s+$//; + } + + # Do some validation + unless(scalar(@certinfo) >= 2 && scalar(@certinfo) <= 3 && length($certinfo[0]) && length($certinfo[1]) ) { + print "\nError: $certfile line '$_' does not contain valid information!\n"; + Usage(); + } + + push @certificates, [@certinfo]; # push data to two dimensional array + } +} + # Remove any existing .sis packages unlink $unsigned_sis_name; unlink $signed_sis_name; @@ -180,15 +234,27 @@ if ($preprocessonly) { exit; } -# Create and sign SIS +# Create SIS. system ("makesis $pkgoutput $unsigned_sis_name"); + +# Sign SIS with certificate info given as an argument. system ("signsis $unsigned_sis_name $signed_sis_name $certificate $key $passphrase"); # Check if creating signed SIS Succeeded stat($signed_sis_name); if( -e _ ) { - print ("\nSuccessfully created $signed_sis_name using certificate $certtext!\n"); + print ("\nSuccessfully created $signed_sis_name using certificate: $certtext!\n"); + # Sign with additional certificates & keys + for my $row ( @certificates ) { + # Get certificate absolute file names, relative paths are relative to certfilepath + my $abscert = File::Spec->rel2abs( $row->[0], $certfilepath); + my $abskey = File::Spec->rel2abs( $row->[1], $certfilepath); + + system ("signsis $signed_sis_name $signed_sis_name $abscert $abskey $row->[2]"); + print ("\tAdditionally signed the SIS with certificate: $row->[0]!\n"); + } + # remove temporary pkg and unsigned sis unlink $pkgoutput; unlink $unsigned_sis_name; -- cgit v0.12