This commit is contained in:
Clint Armstrong 2017-01-10 12:27:17 -05:00
parent c8613243a1
commit f62393b864
2 changed files with 92 additions and 57 deletions

View file

@ -141,11 +141,13 @@ def _new_extension(name, value, critical=0, issuer=None, _pyfree=1):
lhash = None
except AttributeError:
lhash = M2Crypto.m2.x509v3_lhash() # pylint: disable=no-member
ctx = M2Crypto.m2.x509v3_set_conf_lhash(lhash) # pylint: disable=no-member
#ctx not zeroed
ctx = M2Crypto.m2.x509v3_set_conf_lhash(
lhash) # pylint: disable=no-member
# ctx not zeroed
_fix_ctx(ctx, issuer)
x509_ext_ptr = M2Crypto.m2.x509v3_ext_conf(lhash, ctx, name, value) # pylint: disable=no-member
#ctx,lhash freed
x509_ext_ptr = M2Crypto.m2.x509v3_ext_conf(
lhash, ctx, name, value) # pylint: disable=no-member
# ctx,lhash freed
if x509_ext_ptr is None:
raise M2Crypto.X509.X509Error(
@ -354,7 +356,8 @@ def _get_private_key_obj(private_key, passphrase=None):
'''
private_key = _text_or_file(private_key)
private_key = get_pem_entry(private_key, pem_type='RSA PRIVATE KEY')
rsaprivkey = M2Crypto.RSA.load_key_string(private_key, callback=_passphrase_callback(passphrase))
rsaprivkey = M2Crypto.RSA.load_key_string(
private_key, callback=_passphrase_callback(passphrase))
evpprivkey = M2Crypto.EVP.PKey()
evpprivkey.assign_rsa(rsaprivkey)
return evpprivkey
@ -435,15 +438,16 @@ def get_pem_entry(text, pem_type=None):
_match = None
if len(text.splitlines()) == 1 and text.startswith('-----') and text.endswith('-----'):
if len(text.splitlines()) == 1 and text.startswith(
'-----') and text.endswith('-----'):
# mine.get returns the PEM on a single line, we fix this
pem_fixed = []
pem_temp = text
while len(pem_temp) > 0:
if pem_temp.startswith('-----'):
# Grab ----(.*)---- blocks
pem_fixed.append(pem_temp[:pem_temp.index('-----', 5)+5])
pem_temp = pem_temp[pem_temp.index('-----', 5)+5:]
pem_fixed.append(pem_temp[:pem_temp.index('-----', 5) + 5])
pem_temp = pem_temp[pem_temp.index('-----', 5) + 5:]
else:
# grab base64 chunks
if pem_temp[:64].count('-') == 0:
@ -690,7 +694,8 @@ def get_public_key(key, passphrase=None, asObj=False):
rsa = csr.get_pubkey().get_rsa()
if (text.startswith('-----BEGIN PRIVATE KEY-----') or
text.startswith('-----BEGIN RSA PRIVATE KEY-----')):
rsa = M2Crypto.RSA.load_key_string(text, callback=_passphrase_callback(passphrase))
rsa = M2Crypto.RSA.load_key_string(
text, callback=_passphrase_callback(passphrase))
if asObj:
evppubkey = M2Crypto.EVP.PKey()
@ -825,8 +830,11 @@ def create_private_key(path=None,
# pylint: enable=no-member
bio = M2Crypto.BIO.MemoryBuffer()
if passphrase is None:
cipher=None
rsa.save_key_bio(bio, cipher=cipher, callback=_passphrase_callback(passphrase))
cipher = None
rsa.save_key_bio(
bio,
cipher=cipher,
callback=_passphrase_callback(passphrase))
if path:
return write_pem(
@ -967,10 +975,20 @@ def create_crl( # pylint: disable=too-many-arguments,too-many-locals
get_pem_entry(signing_private_key))
try:
crltext = crl.export(cert, key, OpenSSL.crypto.FILETYPE_PEM, days=days_valid, digest=bytes(digest))
crltext = crl.export(
cert,
key,
OpenSSL.crypto.FILETYPE_PEM,
days=days_valid,
digest=bytes(digest))
except TypeError:
log.warning('Error signing crl with specified digest. Are you using pyopenssl 0.15 or newer? The default md5 digest will be used.')
crltext = crl.export(cert, key, OpenSSL.crypto.FILETYPE_PEM, days=days_valid)
log.warning(
'Error signing crl with specified digest. Are you using pyopenssl 0.15 or newer? The default md5 digest will be used.')
crltext = crl.export(
cert,
key,
OpenSSL.crypto.FILETYPE_PEM,
days=days_valid)
if text:
return crltext
@ -1334,14 +1352,15 @@ def create_certificate(
if 'public_key' in kwargs:
# Strip newlines to make passing through as cli functions easier
kwargs['public_key'] = get_public_key(
kwargs['public_key'],
kwargs['public_key'],
passphrase=kwargs['public_key_passphrase']).replace('\n', '')
# Remove system entries in kwargs
# Including listen_in and preqreuired because they are not included
# in STATE_INTERNAL_KEYWORDS
# for salt 2014.7.2
for ignore in list(_STATE_INTERNAL_KEYWORDS) + ['listen_in', 'preqrequired', '__prerequired__']:
for ignore in list(_STATE_INTERNAL_KEYWORDS) + \
['listen_in', 'preqrequired', '__prerequired__']:
kwargs.pop(ignore, None)
cert_txt = __salt__['publish.publish'](
@ -1406,8 +1425,8 @@ def create_certificate(
cert.set_subject(csr.get_subject())
csrexts = read_csr(kwargs['csr'])['X509v3 Extensions']
cert.set_pubkey(get_public_key(kwargs['public_key'],
passphrase=kwargs['public_key_passphrase'], asObj=True))
cert.set_pubkey(get_public_key(kwargs['public_key'],
passphrase=kwargs['public_key_passphrase'], asObj=True))
subject = cert.get_subject()
@ -1466,8 +1485,9 @@ def create_certificate(
return cert_props
if not verify_private_key(private_key=kwargs['signing_private_key'],
passphrase=kwargs['signing_private_key_passphrase'],
public_key=signing_cert):
passphrase=kwargs[
'signing_private_key_passphrase'],
public_key=signing_cert):
raise salt.exceptions.SaltInvocationError(
'signing_private_key: {0} '
'does no match signing_cert: {1}'.format(
@ -1478,7 +1498,7 @@ def create_certificate(
cert.sign(
_get_private_key_obj(kwargs['signing_private_key'],
passphrase=kwargs['signing_private_key_passphrase']),
passphrase=kwargs['signing_private_key_passphrase']),
kwargs['algorithm']
)
@ -1492,7 +1512,7 @@ def create_certificate(
else:
prepend = ''
write_pem(text=cert.as_pem(), path=os.path.join(kwargs['copypath'],
prepend + kwargs['serial_number']+'.crt'),
prepend + kwargs['serial_number'] + '.crt'),
pem_type='CERTIFICATE')
if path:
@ -1552,7 +1572,8 @@ def create_csr(path=None, text=False, **kwargs):
if 'private_key' not in kwargs and 'public_key' in kwargs:
kwargs['private_key'] = kwargs['public_key']
log.warning("OpenSSL no longer allows working with non-signed CSRs. A private_key must be specified. Attempting to use public_key as private_key")
log.warning(
"OpenSSL no longer allows working with non-signed CSRs. A private_key must be specified. Attempting to use public_key as private_key")
if 'private_key' not in kwargs not in kwargs:
raise salt.exceptions.SaltInvocationError('private_key is required')
@ -1563,7 +1584,7 @@ def create_csr(path=None, text=False, **kwargs):
if 'public_key_passphrase' not in kwargs:
kwargs['public_key_passphrase'] = None
csr.set_pubkey(get_public_key(kwargs['public_key'],
passphrase=kwargs['public_key_passphrase'], asObj=True))
passphrase=kwargs['public_key_passphrase'], asObj=True))
# pylint: disable=unused-variable
for entry, num in six.iteritems(subject.nid):
@ -1602,7 +1623,7 @@ def create_csr(path=None, text=False, **kwargs):
csr.add_extensions(extstack)
csr.sign(_get_private_key_obj(kwargs['private_key'],
passphrase=kwargs['public_key_passphrase']), kwargs['algorithm'])
passphrase=kwargs['public_key_passphrase']), kwargs['algorithm'])
if path:
return write_pem(
@ -1636,10 +1657,12 @@ def verify_private_key(private_key, public_key, passphrase=None):
salt '*' x509.verify_private_key private_key=/etc/pki/myca.key \\
public_key=/etc/pki/myca.crt
'''
return bool(get_public_key(private_key, passphrase) == get_public_key(public_key))
return bool(get_public_key(private_key, passphrase)
== get_public_key(public_key))
def verify_signature(certificate, signing_pub_key=None, signing_pub_key_passphrase=None):
def verify_signature(certificate, signing_pub_key=None,
signing_pub_key_passphrase=None):
'''
Verify that ``certificate`` has been signed by ``signing_pub_key``
@ -1665,7 +1688,7 @@ def verify_signature(certificate, signing_pub_key=None, signing_pub_key_passphra
if signing_pub_key:
signing_pub_key = get_public_key(signing_pub_key,
passphrase=signing_pub_key_passphrase, asObj=True)
passphrase=signing_pub_key_passphrase, asObj=True)
return bool(cert.verify(pkey=signing_pub_key) == 1)

View file

@ -188,7 +188,8 @@ def _revoked_to_list(revs):
list_ = []
for rev in revs:
for rev_name, props in six.iteritems(rev): # pylint: disable=unused-variable
for rev_name, props in six.iteritems(
rev): # pylint: disable=unused-variable
dict_ = {}
for prop in props:
for propname, val in six.iteritems(prop):
@ -225,7 +226,8 @@ def _check_private_key(name, bits=2048, passphrase=None, new=False):
current_bits = 0
if os.path.isfile(name):
try:
current_bits = __salt__['x509.get_private_key_size'](private_key=name, passphrase=passphrase)
current_bits = __salt__['x509.get_private_key_size'](
private_key=name, passphrase=passphrase)
except salt.exceptions.SaltInvocationError:
pass
@ -286,11 +288,12 @@ def private_key_managed(name,
file_args, kwargs = _get_file_args(name, **kwargs)
new_key = False
if _check_private_key(name, bits, passphrase, cipher, new):
file_args['contents'] = __salt__['x509.get_pem_entry'](name, pem_type='RSA PRIVATE KEY')
file_args['contents'] = __salt__['x509.get_pem_entry'](
name, pem_type='RSA PRIVATE KEY')
else:
new_key = True
file_args['contents'] = __salt__['x509.create_private_key'](text=True, bits=bits, passphrase=passphrase, cipher=cipher, verbose=verbose)
file_args['contents'] = __salt__['x509.create_private_key'](
text=True, bits=bits, passphrase=passphrase, cipher=cipher, verbose=verbose)
ret = __states__['file.managed'](**file_args)
if ret['changes'] and new_key:
@ -404,12 +407,12 @@ def certificate_managed(name,
new_private_key = False
if managed_private_key:
private_key_args = {
'name': name,
'new': False,
'bits': 2048,
'passphrase': None,
'cipher': 'aes_128_cbc',
'verbose': True
'name': name,
'new': False,
'bits': 2048,
'passphrase': None,
'cipher': 'aes_128_cbc',
'verbose': True
}
private_key_args.update(managed_private_key)
kwargs['public_key_passphrase'] = managed_private_key['passphrase']
@ -422,10 +425,12 @@ def certificate_managed(name,
private_key_args['bits'],
private_key_args['passphrase'],
private_key_args['new']):
private_key = __salt__['x509.get_pem_entry'](private_key_args['name'], pem_type='RSA PRIVATE KEY')
private_key = __salt__['x509.get_pem_entry'](
private_key_args['name'], pem_type='RSA PRIVATE KEY')
else:
new_private_key = True
private_key = __salt__['x509.create_private_key'](text=True, bits=private_key_args['bits'], passphrase=private_key_args['passphrase'], cipher=private_key_args['cipher'], verbose=private_key_args['verbose'])
private_key = __salt__['x509.create_private_key'](text=True, bits=private_key_args['bits'], passphrase=private_key_args[
'passphrase'], cipher=private_key_args['cipher'], verbose=private_key_args['verbose'])
kwargs['public_key'] = private_key
@ -442,7 +447,7 @@ def certificate_managed(name,
try:
current_comp['X509v3 Extensions']['authorityKeyIdentifier'] = (
re.sub(r'serial:([0-9A-F]{2}:)*[0-9A-F]{2}', 'serial:--',
current_comp['X509v3 Extensions']['authorityKeyIdentifier']))
current_comp['X509v3 Extensions']['authorityKeyIdentifier']))
except KeyError:
pass
current_comp.pop('Not Before')
@ -451,8 +456,8 @@ def certificate_managed(name,
current_comp.pop('SHA-256 Finger Print')
current_notafter = current_comp.pop('Not After')
current_days_remaining = (
datetime.datetime.strptime(current_notafter, '%Y-%m-%d %H:%M:%S') -
datetime.datetime.now()).days
datetime.datetime.strptime(current_notafter, '%Y-%m-%d %H:%M:%S') -
datetime.datetime.now()).days
if days_remaining == 0:
days_remaining = current_days_remaining - 1
except salt.exceptions.SaltInvocationError:
@ -461,7 +466,8 @@ def certificate_managed(name,
current = '{0} does not exist.'.format(name)
if 'ca_server' in kwargs and 'signing_policy' not in kwargs:
raise salt.exceptions.SaltInvocationError('signing_policy must be specified if ca_server is.')
raise salt.exceptions.SaltInvocationError(
'signing_policy must be specified if ca_server is.')
new = __salt__['x509.create_certificate'](testrun=True, **kwargs)
@ -474,7 +480,7 @@ def certificate_managed(name,
try:
new_comp['X509v3 Extensions']['authorityKeyIdentifier'] = (
re.sub(r'serial:([0-9A-F]{2}:)*[0-9A-F]{2}', 'serial:--',
new_comp['X509v3 Extensions']['authorityKeyIdentifier']))
new_comp['X509v3 Extensions']['authorityKeyIdentifier']))
except KeyError:
pass
new_comp.pop('Not Before')
@ -490,11 +496,13 @@ def certificate_managed(name,
if (current_comp == new_comp and
current_days_remaining > days_remaining and
__salt__['x509.verify_signature'](name, new_issuer_public_key)):
certificate = __salt__['x509.get_pem_entry'](name, pem_type='CERTIFICATE')
certificate = __salt__['x509.get_pem_entry'](
name, pem_type='CERTIFICATE')
else:
if rotate_private_key and not new_private_key:
new_private_key = True
private_key = __salt__['x509.create_private_key'](text=True, bits=private_key_args['bits'], verbose=private_key_args['verbose'])
private_key = __salt__['x509.create_private_key'](
text=True, bits=private_key_args['bits'], verbose=private_key_args['verbose'])
kwargs['public_key'] = private_key
new_certificate = True
certificate = __salt__['x509.create_certificate'](text=True, **kwargs)
@ -506,7 +514,8 @@ def certificate_managed(name,
file_args['contents'] = private_key
else:
private_file_args = copy.deepcopy(file_args)
unique_private_file_args = _get_file_args(private_key_args['name'], **private_key_args)
unique_private_file_args = _get_file_args(
private_key_args['name'], **private_key_args)
private_file_args.update(unique_private_file_args)
private_file_args['contents'] = private_key
private_ret = __states__['file.managed'](**private_file_args)
@ -516,7 +525,8 @@ def certificate_managed(name,
file_args['contents'] += certificate
for append_cert in append_certs:
file_args['contents'] += __salt__['x509.get_pem_entry'](append_cert, pem_type='CERTIFICATE')
file_args[
'contents'] += __salt__['x509.get_pem_entry'](append_cert, pem_type='CERTIFICATE')
file_args['show_changes'] = False
ret = __states__['file.managed'](**file_args)
@ -531,8 +541,8 @@ def certificate_managed(name,
ret['changes']['Private Key'] = 'New private key generated'
if new_certificate:
ret['changes']['Certificate'] = {
'Old': current,
'New': __salt__['x509.read_certificate'](certificate=certificate) }
'Old': current,
'New': __salt__['x509.read_certificate'](certificate=certificate)}
return ret
@ -616,8 +626,8 @@ def crl_managed(name,
current_comp.pop('Last Update')
current_notafter = current_comp.pop('Next Update')
current_days_remaining = (
datetime.datetime.strptime(current_notafter, '%Y-%m-%d %H:%M:%S') -
datetime.datetime.now()).days
datetime.datetime.strptime(current_notafter, '%Y-%m-%d %H:%M:%S') -
datetime.datetime.now()).days
if days_remaining == 0:
days_remaining = current_days_remaining - 1
except salt.exceptions.SaltInvocationError:
@ -626,7 +636,7 @@ def crl_managed(name,
current = '{0} does not exist.'.format(name)
new_crl = __salt__['x509.create_crl'](text=True, signing_private_key=signing_private_key,
signing_cert=signing_cert, revoked=revoked, days_valid=days_valid, digest=digest, include_expired=include_expired)
signing_cert=signing_cert, revoked=revoked, days_valid=days_valid, digest=digest, include_expired=include_expired)
new = __salt__['x509.read_crl'](crl=new_crl)
new_comp = new.copy()
@ -638,14 +648,16 @@ def crl_managed(name,
if (current_comp == new_comp and
current_days_remaining > days_remaining and
__salt__['x509.verify_crl'](name, signing_cert)):
file_args['contents'] = __salt__['x509.get_pem_entry'](name, pem_type='X509 CRL')
file_args['contents'] = __salt__[
'x509.get_pem_entry'](name, pem_type='X509 CRL')
else:
new_crl = True
file_args['contents'] = new_crl
ret = __states__['file.managed'](**file_args)
if new_crl:
ret['changes'] = {'Old': current, 'New': __salt__['x509.read_crl'](crl=new_crl)}
ret['changes'] = {'Old': current, 'New': __salt__[
'x509.read_crl'](crl=new_crl)}
return ret