#! --PERL--
# -*- indent-tabs-mode: nil; -*-
# vim:ft=perl:et:sw=4
# $Id$
# Sympa - SYsteme de Multi-Postage Automatique
#
# Copyright (c) 1997, 1998, 1999 Institut Pasteur & Christophe Wolfhugel
# Copyright (c) 1997, 1998, 1999, 2000, 2001, 2002, 2003, 2004, 2005,
# 2006, 2007, 2008, 2009, 2010, 2011 Comite Reseau des Universites
# Copyright (c) 2011, 2012, 2013, 2014, 2015, 2016, 2017 GIP RENATER
#
# This program is free software; you can redistribute it and/or modify
# it under the terms of the GNU General Public License as published by
# the Free Software Foundation; either version 2 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see .
use lib '--modulesdir--';
use strict;
use warnings;
use Getopt::Long;
use Conf;
use Sympa::Constants;
use Sympa::DatabaseManager;
use Sympa::List;
my $sympa_conf_file = Sympa::Constants::CONFIG;
## Load sympa config
unless (Conf::load($sympa_conf_file)) {
die 'config_error';
}
## Probe Db if defined
if ($Conf::Conf{'db_name'} and $Conf::Conf{'db_type'}) {
unless (Sympa::DatabaseManager::probe_db()) {
die('Database %s defined in sympa.conf has not the right structure or is unreachable. If you don\'t use any database, comment db_xxx parameters in sympa.conf',
$Conf::Conf{'db_name'}
);
}
}
my $openssl;
foreach my $path (
split(/:/, $ENV{PATH} || ''),
qw(/usr/local/bin /usr/local/ssl/bin /opt/local/bin /usr/sfw/bin /usr/bin)
) {
my $file = $path . '/openssl';
if (-x $file) {
$openssl = $file;
last;
}
}
my $home_sympa = $Conf::Conf{'home'};
my $outpass = $Conf::Conf{'key_passwd'};
my $etc_dir = $Conf::Conf{'etc'};
## Check option
my %options;
GetOptions(\%main::options, 'pkcs12=s', 'listname=s', 'robot=s', 'help|h');
$main::options{'foreground'} = 1;
my $listname = $main::options{'listname'};
my $robot = $main::options{'robot'};
my $p12input = $main::options{'pkcs12'};
my ($cert, $privatekey, $inpass, $key);
if ( ($main::options{'help'} ne '')
|| !(-r $main::options{'pkcs12'})
|| (($main::options{'listname'} ne '') && ($main::options{'robot'} ne ''))
) {
print_usage();
} else {
if ($listname) {
my $self = Sympa::List->new($listname, $robot);
$cert = $self->{'dir'} . '/cert.pem';
$privatekey = $self->{'dir'} . '/private_key';
unless (-d $self->{'dir'}) {
printf
"unknown list $listname (directory $self->{'dir'} not found)\n";
die;
}
} elsif ($robot) {
if (-d $Conf::Conf{'etc'} . '/' . $robot) {
$cert = $Conf::Conf{'etc'} . '/' . $robot . '/cert.pem';
$privatekey = $Conf::Conf{'etc'} . '/' . $robot . '/private_key';
} else {
$cert = $Conf::Conf{'etc'} . '/cert.pem';
$privatekey = $Conf::Conf{'etc'} . '/private_key';
}
}
if (-r "$cert") {
printf "$cert certificate already exists\n";
die;
}
if (-r "$privatekey") {
printf "$privatekey already exists\n";
die;
}
unless ($openssl) {
printf
"You must set PATH environment variable to use openssl command line utility.\n";
die;
}
my $pipeout;
system 'stty', '-echo';
printf "password to access to $p12input :";
chop($inpass = );
print "\n";
system 'stty', 'echo';
open $pipeout, '|-', $openssl, 'pkcs12',
'-in' => $p12input,
'-out' => $cert,
'-nokeys', '-clcerts', '-passin' => 'stdin';
print $pipeout "$inpass\n";
close $pipeout;
unless ($outpass) {
system 'stty', '-echo';
printf "sympa password to protect list private_key $key:";
chop($outpass = );
print "\n";
system 'stty', 'echo';
}
open $pipeout, '|-', $openssl, 'pkcs12',
'-in' => $p12input,
'-out' => $privatekey,
'-nocerts',
'-passin' => 'stdin',
'-des3', '-passout' => 'stdin';
print $pipeout "$inpass\n$outpass\n";
close $pipeout;
printf "$privatekey and $cert created.\n";
exit;
}
sub print_usage {
printf "
Usage p12topem.pl --pkcs12 --listname or
p12topem.pl --pkcs12 --robot
This script is intended to convert a PKCS#12 certificates in PEM format
using Openssl. This is useful because most PKI providerd deliver certificates
using a web interface so the certificate is stored in your browser.
When exporting a certificate from a browser (Netscape, IE, Mozilla etc)
the result is stored using PKCS#12 format.Sympa requires a pair of PEM
certificate and private key. You must then convert your pkcs#12 into PEM.
For a list certificate, the file will be installed in
$home_sympa//cert.pem and $home_sympa//private_key
For Sympa itself a certificate will be installed in
$Conf::Conf{'etc'}//cert.pem and $Conf::Conf{'etc'}//private_key or
$Conf::Conf{'etc'}/cert.pem and Conf{'etc'}/private_key
You are then prompted for inpassword (the password used to encrypt the
pkc#12 file).\n";
unless ($outpass) {
printf
"Because you did not configure Sympa's password \"key_passwd\" in
sympa.conf you will also be prompted for the password used by sympa to access
to the list private key)\n";
}
}