@ -29,10 +29,11 @@ options:
type : str
type : str
default : export
default : export
choices : [ export , parse ]
choices : [ export , parse ]
ca _certificates:
other _certificates:
description :
description :
- List of CA certificate to include .
- List of other certificates to include . Pre 2.8 this parameter was called C ( ca_certificates )
type : list
type : list
aliases : [ ca_certificates ]
certificate_path :
certificate_path :
description :
description :
- The path to read certificates and private keys from .
- The path to read certificates and private keys from .
@ -111,7 +112,7 @@ EXAMPLES = r'''
friendly_name : raclette
friendly_name : raclette
privatekey_path : / opt / certs / keys / key . pem
privatekey_path : / opt / certs / keys / key . pem
certificate_path : / opt / certs / cert . pem
certificate_path : / opt / certs / cert . pem
ca _certificates: / opt / certs / ca . pem
other _certificates: / opt / certs / ca . pem
state : present
state : present
- name : Change PKCS #12 file permission
- name : Change PKCS #12 file permission
@ -121,7 +122,7 @@ EXAMPLES = r'''
friendly_name : raclette
friendly_name : raclette
privatekey_path : / opt / certs / keys / key . pem
privatekey_path : / opt / certs / keys / key . pem
certificate_path : / opt / certs / cert . pem
certificate_path : / opt / certs / cert . pem
ca _certificates: / opt / certs / ca . pem
other _certificates: / opt / certs / ca . pem
state : present
state : present
mode : ' 0600 '
mode : ' 0600 '
@ -133,7 +134,7 @@ EXAMPLES = r'''
friendly_name : raclette
friendly_name : raclette
privatekey_path : / opt / certs / keys / key . pem
privatekey_path : / opt / certs / keys / key . pem
certificate_path : / opt / certs / cert . pem
certificate_path : / opt / certs / cert . pem
ca _certificates: / opt / certs / ca . pem
other _certificates: / opt / certs / ca . pem
state : present
state : present
mode : ' 0600 '
mode : ' 0600 '
force : yes
force : yes
@ -201,7 +202,7 @@ class Pkcs(crypto_utils.OpenSSLObject):
module . check_mode
module . check_mode
)
)
self . action = module . params [ ' action ' ]
self . action = module . params [ ' action ' ]
self . ca_certificates = module . params [ ' ca _certificates' ]
self . other_certificates = module . params [ ' other _certificates' ]
self . certificate_path = module . params [ ' certificate_path ' ]
self . certificate_path = module . params [ ' certificate_path ' ]
self . friendly_name = module . params [ ' friendly_name ' ]
self . friendly_name = module . params [ ' friendly_name ' ]
self . iter_size = module . params [ ' iter_size ' ]
self . iter_size = module . params [ ' iter_size ' ]
@ -237,7 +238,50 @@ class Pkcs(crypto_utils.OpenSSLObject):
if not state_and_perms :
if not state_and_perms :
return state_and_perms
return state_and_perms
return _check_pkey_passphrase
if os . path . exists ( self . path ) and module . params [ ' action ' ] == ' export ' :
dummy = self . generate ( module )
self . src = self . path
try :
pkcs12_privatekey , pkcs12_certificate , pkcs12_other_certificates , pkcs12_friendly_name = self . parse ( )
except crypto . Error :
return False
if ( pkcs12_privatekey is not None ) and ( self . privatekey_path is not None ) :
expected_pkey = crypto . dump_privatekey ( crypto . FILETYPE_PEM ,
self . pkcs12 . get_privatekey ( ) )
if pkcs12_privatekey != expected_pkey :
return False
elif bool ( pkcs12_privatekey ) != bool ( self . privatekey_path ) :
return False
if ( pkcs12_certificate is not None ) and ( self . certificate_path is not None ) :
expected_cert = crypto . dump_certificate ( crypto . FILETYPE_PEM ,
self . pkcs12 . get_certificate ( ) )
if pkcs12_certificate != expected_cert :
return False
elif bool ( pkcs12_certificate ) != bool ( self . certificate_path ) :
return False
if ( pkcs12_other_certificates is not None ) and ( self . other_certificates is not None ) :
expected_other_certs = [ crypto . dump_certificate ( crypto . FILETYPE_PEM ,
other_cert ) for other_cert in self . pkcs12 . get_ca_certificates ( ) ]
if set ( pkcs12_other_certificates ) != set ( expected_other_certs ) :
return False
elif bool ( pkcs12_other_certificates ) != bool ( self . other_certificates ) :
return False
if pkcs12_privatekey :
# This check is required because pyOpenSSL will not return a firendly name
# if the private key is not set in the file
if ( ( self . pkcs12 . get_friendlyname ( ) is not None ) and ( pkcs12_friendly_name is not None ) ) :
if self . pkcs12 . get_friendlyname ( ) != pkcs12_friendly_name :
return False
elif bool ( self . pkcs12 . get_friendlyname ( ) ) != bool ( pkcs12_friendly_name ) :
return False
else :
return False
return _check_pkey_passphrase ( )
def dump ( self ) :
def dump ( self ) :
""" Serialize the object into a dictionary. """
""" Serialize the object into a dictionary. """
@ -254,13 +298,12 @@ class Pkcs(crypto_utils.OpenSSLObject):
def generate ( self , module ) :
def generate ( self , module ) :
""" Generate PKCS#12 file archive. """
""" Generate PKCS#12 file archive. """
self . pkcs12 = crypto . PKCS12 ( )
self . pkcs12 = crypto . PKCS12 ( )
if self . ca _certificates:
if self . other _certificates:
ca_certs = [ crypto_utils . load_certificate ( ca_cert ) for ca _cert
other_certs = [ crypto_utils . load_certificate ( other_cert ) for other _cert
in self . ca _certificates]
in self . other _certificates]
self . pkcs12 . set_ca_certificates ( ca _certs)
self . pkcs12 . set_ca_certificates ( other _certs)
if self . certificate_path :
if self . certificate_path :
self . pkcs12 . set_certificate ( crypto_utils . load_certificate (
self . pkcs12 . set_certificate ( crypto_utils . load_certificate (
@ -278,20 +321,14 @@ class Pkcs(crypto_utils.OpenSSLObject):
except crypto_utils . OpenSSLBadPassphraseError as exc :
except crypto_utils . OpenSSLBadPassphraseError as exc :
raise PkcsError ( exc )
raise PkcsError ( exc )
if self . backup :
return self . pkcs12 . export ( self . passphrase , self . iter_size , self . maciter_size )
self . backup_file = module . backup_local ( self . path )
crypto_utils . write_file (
module ,
self . pkcs12 . export ( self . passphrase , self . iter_size , self . maciter_size ) ,
0o600
)
def remove ( self , module ) :
def remove ( self , module ) :
if self . backup :
if self . backup :
self . backup_file = module . backup_local ( self . path )
self . backup_file = module . backup_local ( self . path )
super ( Pkcs , self ) . remove ( module )
super ( Pkcs , self ) . remove ( module )
def parse ( self , module ):
def parse ( self ):
""" Read PKCS#12 file. """
""" Read PKCS#12 file. """
try :
try :
@ -303,17 +340,29 @@ class Pkcs(crypto_utils.OpenSSLObject):
p12 . get_privatekey ( ) )
p12 . get_privatekey ( ) )
crt = crypto . dump_certificate ( crypto . FILETYPE_PEM ,
crt = crypto . dump_certificate ( crypto . FILETYPE_PEM ,
p12 . get_certificate ( ) )
p12 . get_certificate ( ) )
other_certs = [ ]
if p12 . get_ca_certificates ( ) is not None :
other_certs = [ crypto . dump_certificate ( crypto . FILETYPE_PEM ,
other_cert ) for other_cert in p12 . get_ca_certificates ( ) ]
crypto_utils . write_file ( module , b ' %s %s ' % ( pkey , crt ) )
friendly_name = p12 . get_friendlyname ( )
return ( pkey , crt , other_certs , friendly_name )
except IOError as exc :
except IOError as exc :
raise PkcsError ( exc )
raise PkcsError ( exc )
def write ( self , module , content , mode = None ) :
""" Write the PKCS#12 file. """
if self . backup :
self . backup_file = module . backup_local ( self . path )
crypto_utils . write_file ( module , content , mode )
def main ( ) :
def main ( ) :
argument_spec = dict (
argument_spec = dict (
action = dict ( type = ' str ' , default = ' export ' , choices = [ ' export ' , ' parse ' ] ) ,
action = dict ( type = ' str ' , default = ' export ' , choices = [ ' export ' , ' parse ' ] ) ,
ca_certificates = dict ( type = ' list ' , elements = ' path ' ) ,
other _certificates= dict ( type = ' list ' , elements = ' path ' , aliases = [ ' ca_certificates ' ] ) ,
certificate_path = dict ( type = ' path ' ) ,
certificate_path = dict ( type = ' path ' ) ,
force = dict ( type = ' bool ' , default = False ) ,
force = dict ( type = ' bool ' , default = False ) ,
friendly_name = dict ( type = ' str ' , aliases = [ ' name ' ] ) ,
friendly_name = dict ( type = ' str ' , aliases = [ ' name ' ] ) ,
@ -363,10 +412,13 @@ def main():
if module . params [ ' action ' ] == ' export ' :
if module . params [ ' action ' ] == ' export ' :
if not module . params [ ' friendly_name ' ] :
if not module . params [ ' friendly_name ' ] :
module . fail_json ( msg = ' Friendly_name is required ' )
module . fail_json ( msg = ' Friendly_name is required ' )
pkcs12 . generate ( module )
pkcs12_content = pkcs12 . generate ( module )
pkcs12 . write ( module , pkcs12_content , 0o600 )
changed = True
changed = True
else :
else :
pkcs12 . parse ( module )
pkey , cert , other_certs , friendly_name = pkcs12 . parse ( )
dump_content = ' %s %s %s ' % ( to_native ( pkey ) , to_native ( cert ) , to_native ( b ' ' . join ( other_certs ) ) )
pkcs12 . write ( module , to_bytes ( dump_content ) )
file_args = module . load_file_common_arguments ( module . params )
file_args = module . load_file_common_arguments ( module . params )
if module . set_fs_attributes_if_different ( file_args , changed ) :
if module . set_fs_attributes_if_different ( file_args , changed ) :