saltstack / salt

Software to automate the management and configuration of any infrastructure or application at scale. Install Salt from the Salt package repositories here:
https://docs.saltproject.io/salt/install-guide/en/latest/
Apache License 2.0
14.19k stars 5.48k forks source link

x509 state or module cannot generate password protected private keys #38081

Closed haraldrudell closed 6 years ago

haraldrudell commented 7 years ago

Description of Issue/Question

When generating certificates for client certificate authentication sometimes a password is desirable for the private key, similar to echo abc >phrase.txt && openssl genrsa -passout file:phrase.txt

x509 state or module cannot generate password protected private keys

Version: 2016.11.0+ds-1

meanwhile one can do

openssl rsa -in key_from_salt.pem -aes256 -passout file:phrase.txt -out encrypted_key.pem
Ch3LL commented 7 years ago

@haraldrudell agreed this would be nice to implement. Will add as a feature request. Thanks!

MorphBonehunter commented 7 years ago

I ask myself how this could be implemented? I'm generally a friend on generated Passphrases. So maybe it is possible to define another parameter on the "create_private_key" function which saves an generated (there is for ex. an pwgen python module in the wild) pass in an defined file. Maybe there are use cases on which the user wants to define an pass (in pillar data) so it should be possible to save this one to the above mentioned file (maybe for reading with ssl_password_file from nginx). Also this article from @clinta is worth a read: https://clinta.github.io/random-local-passwords/

clinta commented 7 years ago

What is the intended use case here? I'm having trouble thinking of how this could be implemented in a useful way.

The generated passwords for local login works because only a hash needs to be distributed to the minions, so once it's generated, none of the automated processes ever need to know the plain text again. But for the state module to be able to check and verify a private key is in the correct state the clear text password must be present in the state template. Which means it will be cached on the minion and accessible to anyone on the system with root privileges anyway.

I can't think of a situation when this would provide anything but an illusion of security. Except perhaps for interactive use of the execution module. But not for states.

MorphBonehunter commented 7 years ago

@clinta I'm aware that your article isn't about the same topic as the requests here, but i thought it is a good starting point. You are right, it does't make much sense to generate an key on an system with password and use it on the same system with nothing more than read the password from the file next to the key (but on the other hand it is possible with nginx...so maybe there is an use case). But another use case is an complete PKI for lets say OpenVPN where the PKI itself is an hardened system in the back which can generate key/certs for authentication on an Server. So the key and cert could send to an customer and the pass could submitted on an other medium (yes i know, it's not the best was, but this is an real use case and not everyone could generate an CSR or even know what this is) for login in an isolated network. Same is applicable for SSL Client Cerificates (which is literal the same). So with salt this is an easy automated process and could also generate the crl in case of revoke or compromise etc.

haraldrudell commented 7 years ago
  1. The password should be stored in the file system on the target minion, therefore only accessible to a root user on the minion to which they deploy.
  2. If the certificates are generated to a file system folder on the master itself as a step prior to being distributed, the passwords will only be on the master.
    1. It is true that Salt master presently only has a single, shared file server which is a separate issue.
    2. In order to securely store and use passwords in an ext-pillar key, this currently requires a separate Salt instance
  3. If private key passwords were not useful, they would not be part of openssl.
  4. An advanced user that rely on the x509 state module for all pki needs will want this feature.
    1. At present, cmd.run and onchanges can be used to implement this as a separate step

x509 is a great module, because before it, script-based pki generation was difficult due to the general reliance on complex parameter files

clinta commented 7 years ago

My thinking is that if the password and key file must be accessible to the root user (and the user who the salt minion runs as if that is different), the maximum level of security you can have for the private key is what you can achieve by file permissions. So applying those permissions on an unencrypted private key file would result in the same level of security.

The use case of generating keys and certs on one system to be shipped off to another system is one I haven't thought of which could be useful. That's why I asked the question.

I started writing this, but when I realized that the password must be available every time the state is checking to see if changes are required had me wondering if it was all that useful anyway.

MorphBonehunter commented 7 years ago

@clinta it seems that i can not get this to work. I've created a test sls:

pki_private_key:
    x509.private_key_managed:
        - name: /tmp/ca.key
        - bits: 4096
        - passphrase: test2
        - cipher: aes_256_cbc
        - backup: True

pki_ca_cert:
    x509.certificate_managed:
        - name: /tmp/ca.crt
        - signing_private_key: /tmp/ca.key
        - signing_private_key_passphrase: test2
        - CN: test.ca
        - C: DE
        - ST: ST
        - L: Location
        - Email: test@test.ca
        - basicConstraints: "critical CA:true"
        - keyUsage: "critical cRLSign, keyCertSign"
        - subjectKeyIdentifier: hash
        - authorityKeyIdentifier: keyid,issuer:always
        - days_valid: 3650
        - days_remaining: 0
        - backup: True
        - require:
            - x509: pki_private_key

If i run state.apply i got the following error:

----------
          ID: pki_private_key
    Function: x509.private_key_managed
        Name: /tmp/ca.key
      Result: True
     Comment: File /tmp/ca.key updated
     Started: 19:45:59.295605
    Duration: 1222.628 ms
     Changes:   Invalid Changes data: New private key generated
----------
          ID: pki_ca_cert
    Function: x509.certificate_managed
        Name: /tmp/ca.crt
      Result: False
     Comment: An exception occurred in this state: Traceback (most recent call last):
                File "/usr/lib/python2.7/site-packages/salt/state.py", line 1745, in call
                  **cdata['kwargs'])
                File "/usr/lib/python2.7/site-packages/salt/loader.py", line 1702, in wrapper
                  return f(*args, **kwargs)
                File "/usr/lib/python2.7/site-packages/salt/states/x509.py", line 473, in certificate_managed
                  new = __salt__['x509.create_certificate'](testrun=True, **kwargs)
                File "/usr/lib/python2.7/site-packages/salt/modules/x509.py", line 1429, in create_certificate
                  passphrase=kwargs['public_key_passphrase'], asObj=True))
                File "/usr/lib/python2.7/site-packages/salt/modules/x509.py", line 698, in get_public_key
                  text, callback=_passphrase_callback(passphrase))
                File "/usr/lib/python2.7/site-packages/M2Crypto/RSA.py", line 399, in load_key_string
                  return load_key_bio(bio, callback)
                File "/usr/lib/python2.7/site-packages/M2Crypto/RSA.py", line 379, in load_key_bio
                  rsa_error()
                File "/usr/lib/python2.7/site-packages/M2Crypto/RSA.py", line 309, in rsa_error
                  raise RSAError(m2.err_reason_error_string(m2.err_get_error()))
              RSAError: bad password read
     Started: 19:46:00.519129
    Duration: 10.162 ms
     Changes:

But i can decrypt the ca.key with the password test with openssl rsa.

Second thing: If i try to change the password in the sls (as only change) and the keyfile exists i got the following error:

----------
          ID: pki_private_key
    Function: x509.private_key_managed
        Name: /tmp/ca.key
      Result: False
     Comment: An exception occurred in this state: Traceback (most recent call last):
                File "/usr/lib/python2.7/site-packages/salt/state.py", line 1745, in call
                  **cdata['kwargs'])
                File "/usr/lib/python2.7/site-packages/salt/loader.py", line 1702, in wrapper
                  return f(*args, **kwargs)
                File "/usr/lib/python2.7/site-packages/salt/states/x509.py", line 289, in private_key_managed
                  if _check_private_key(name, bits, passphrase, new):
                File "/usr/lib/python2.7/site-packages/salt/states/x509.py", line 229, in _check_private_key
                  private_key=name, passphrase=passphrase)
                File "/usr/lib/python2.7/site-packages/salt/modules/x509.py", line 722, in get_private_key_size
                  return _get_private_key_obj(private_key, passphrase).size() * 8
                File "/usr/lib/python2.7/site-packages/salt/modules/x509.py", line 360, in _get_private_key_obj
                  private_key, callback=_passphrase_callback(passphrase))
                File "/usr/lib/python2.7/site-packages/M2Crypto/RSA.py", line 399, in load_key_string
                  return load_key_bio(bio, callback)
                File "/usr/lib/python2.7/site-packages/M2Crypto/RSA.py", line 379, in load_key_bio
                  rsa_error()
                File "/usr/lib/python2.7/site-packages/M2Crypto/RSA.py", line 309, in rsa_error
                  raise RSAError(m2.err_reason_error_string(m2.err_get_error()))
              RSAError: bad decrypt
     Started: 19:47:21.944378
    Duration: 12.958 ms
     Changes:   
----------
          ID: pki_ca_cert
    Function: x509.certificate_managed
        Name: /tmp/ca.crt
      Result: False
     Comment: One or more requisite failed: x509-test.pki_private_key
     Changes:

So maybe i did it wrong?

clinta commented 7 years ago

Can you do a salt-call --versions-report? I'm wondering if it my be an issue with the version of M2Crypto.

MorphBonehunter commented 7 years ago

Running salt on Arch Linux

Salt Version:
           Salt: 2016.11.0

Dependency Versions:
           cffi: 1.9.1
       cherrypy: 8.9.1
       dateutil: Not Installed
          gitdb: Not Installed
      gitpython: Not Installed
          ioflo: Not Installed
         Jinja2: 2.9.4
        libgit2: Not Installed
        libnacl: Not Installed
       M2Crypto: 0.24.0
           Mako: Not Installed
   msgpack-pure: Not Installed
 msgpack-python: 0.4.8
   mysql-python: Not Installed
      pycparser: 2.17
       pycrypto: 2.6.1
         pygit2: Not Installed
         Python: 2.7.13 (default, Dec 21 2016, 07:16:46)
   python-gnupg: Not Installed
         PyYAML: 3.12
          PyZMQ: 16.0.2
           RAET: Not Installed
          smmap: Not Installed
        timelib: Not Installed
        Tornado: 4.4.2
            ZMQ: 4.2.0

System Versions:
           dist:   
        machine: x86_64
        release: 4.8.13-1-ARCH
         system: Linux
        version: Not Installed

Salt is build from branch 2016.11 commit 5ff5e97598d6d9aee76f18b0f2ddd76ea95e12f8

clinta commented 7 years ago

This is a bug. The PR above fixes it. You can also work around it by adding public_key_passphrase: test2 to your certificate.managed state.

clinta commented 7 years ago

I'll have another PR to address the changing password issue.

clinta commented 7 years ago

So, I'm not quite sure what should be done about changing passwords. An easy solution is to just regenerate the private key whenever decryption fails. But that would cause the certificate to also be regenerated with a new key and could wreck havoc. To allow the same key to be re-encrypted with a new password would require adding even more options so that an old passphrase can be specified as well.

MorphBonehunter commented 7 years ago

Ok, so this could cause trouble. So maybe the best option is to specify an "old_password" which is used if the decryption doesn't work and if this works encrypt with the new pass. Unfortunately i'm not an developer and so i don't know which dependencies this have to the other functions (generate cert/csr etc) and how much work this could be.

MorphBonehunter commented 7 years ago

@clinta Thanks for the PR, the certificate.managed works now. But unfortunately i step on another Problem, the x509.crl_managed doesn't work. I extend my testcase a little bit:

pki_private_key:
    x509.private_key_managed:
        - name: /tmp/ca.key
        - bits: 4096
        - passphrase: test
        - cipher: aes_256_cbc
        - backup: True

pki_ca_cert:
    x509.certificate_managed:
        - name: /tmp/ca.crt
        - signing_private_key: /tmp/ca.key
        - signing_private_key_passphrase: test
        - CN: test.ca
        - C: DE
        - ST: ST
        - L: Location
        - Email: test@test.ca
        - basicConstraints: "critical CA:true"
        - keyUsage: "critical cRLSign, keyCertSign"
        - subjectKeyIdentifier: hash
        - authorityKeyIdentifier: keyid,issuer:always
        - days_valid: 3650
        - days_remaining: 0
        - backup: True
        - require:
            - x509: pki_private_key

pki_crl:
    x509.crl_managed:
        - name: /tmp/ca.crl
        - signing_private_key: /tmp/ca.key
        - signing_private_key_passphrase: test
        - signing_cert: /tmp/ca.crt
        - digest: sha256
        - days_valid: 30
        - days_remaining: 5
        - backup: True
        - require:
            - x509: pki_ca_cert

pki_cert:
    x509.certificate_managed:
        - name: /tmp/cert.crt
        - signing_private_key: /tmp/ca.key
        - signing_private_key_passphrase: test
        - signing_cert: /tmp/ca.crt
        - basicConstraints: "critical CA:false"
        - nsComment: "salt managed webserver CERT"
        - subjectKeyIdentifier: hash
        - authorityKeyIdentifier: keyid,issuer:always
        - extendedKeyUsage: serverAuth,clientAuth
        - keyUsage: "critical digitalSignature, keyEncipherment"
        - days_valid: 30
        - days_remaining: 5
        - backup: True
        - require:
            - x509: pki_ca_cert

So if i run salt-call state.apply x509-test -l debug i got (only relevant parts):

[INFO    ] Running state [/tmp/ca.key] at time 09:47:31.448915
[INFO    ] Executing state x509.private_key_managed for /tmp/ca.key
.............................................................................................................................................................++
...++
[DEBUG   ] LazyLoaded file.managed
[DEBUG   ] LazyLoaded file.source_list
[INFO    ] New private key generated
[INFO    ] Completed state [/tmp/ca.key] at time 09:47:34.154869 duration_in_ms=2705.954
[INFO    ] Running state [/tmp/ca.crt] at time 09:47:34.155896
[INFO    ] Executing state x509.certificate_managed for /tmp/ca.crt
[INFO    ] {'Certificate': {'New': {'MD5 Finger Print': '84:19:A2:71:91:B4:09:FB:52:35:F5:ED:45:91:AB:D3', 'Version': 3L, 'Key Size': 4096, 'Not After': '2027-01-24 08:47:34', 'X509v3 Extensions': OrderedDict([('basicConstraints', 'critical CA:TRUE'), ('keyUsage', 'critical Certificate Sign, CRL Sign'), ('subjectKeyIdentifier', '8F:B8:B0:DF:54:2C:10:CC:25:2C:2A:78:D5:68:5C:64:16:4F:DF:BF'), ('authorityKeyIdentifier', 'keyid:8F:B8:B0:DF:54:2C:10:CC:25:2C:2A:78:D5:68:5C:64:16:4F:DF:BF\nDirName:/C=DE/CN=test.ca/L=Location/ST=ST/emailAddress=test@test.ca\nserial:C2:99:4A:50:09:6C:C3:B2\n')]), 'Subject Hash': '49:E9:44:4B', 'SHA1 Finger Print': '31:A0:21:08:3E:D5:3B:D7:3F:31:33:85:F5:2D:46:21:2D:A5:EF:54', 'SHA-256 Finger Print': '73:ED:BF:97:4E:8E:62:ED:1E:D9:B4:05:94:9E:D6:83:5C:58:0F:98:D4:87:4F:7C:A0:02:4D:43:79:BF:46:32', 'Serial Number': 'C2:99:4A:50:09:6C:C3:B2', 'Public Key': '-----BEGIN PUBLIC KEY-----\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAq9YSjWcIF/iIawdIJi9S\nFrnYJpUr+0uwFnN+EJMln0/D8+5IVhrKeHSbcrgQWPBUXPrPODqfvqUnGbxkFphC\nvBybLzK6eF3IcsL8UMuOJjGHCQtiG8cHt3ZyKUE4OOIBRAgRqqY9swweUH+Wy3Iu\nVHac9eqfht5r+MYKY6DIsKTebLvztQ3uOPv4fGWYVHTmzUKrDFqwPgU9IsEXU7L/\np/rjb0lp2nLa71Spjdrx+km7mIHr7EohYM+rBNzba9oiuG42ihINkTJat8s7y/da\nJNA6+SrpbjqP7AFVUCCqJYVaSAALp3CqhVyner3lrhSMcGmsM1CnZKYj18CVJ+pB\njzbvYzKIX+yrzhXQISDRq1VlM4WO+pAyrea8B6VwLqn2JFNfw+J25PmSpku/mTZv\nS5rhXyvPW+HrfyrEdqIJ6G6w1jHWcT+9zFDU/J5u7jNcGQ5GeiDhVwLq5hWtoJlq\ndoAfx60h5JX5xeiLE8iwveBU/mLzR35DMhV987EliHgQltU471WctSFgwhINkPGw\nwDFUlERNp+Xwg0ondEzTD+a8hPePDqe1bzH43WoeWMH/grD2bLGGUITiq/VuFppO\nC7m4tXQwh+1y0Bib6ohnTwhV5D0yCV84x4jJ0lc+E+NvoGttRVVyVavKskhvR0RW\nsgSl/y8gOsxdpyDHmHwhMo0CAwEAAQ==\n-----END PUBLIC KEY-----\n', 'Issuer Hash': '49:E9:44:4B', 'Subject': {'C': 'DE', 'SP': 'ST', 'emailAddress': 'test@test.ca', 'CN': 'test.ca', 'L': 'Location'}, 'Not Before': '2017-01-26 08:47:34', 'Issuer': {'C': 'DE', 'SP': 'ST', 'emailAddress': 'test@test.ca', 'CN': 'test.ca', 'L': 'Location'}}, 'Old': '/tmp/ca.crt does not exist.'}}
[INFO    ] Completed state [/tmp/ca.crt] at time 09:47:34.217055 duration_in_ms=61.159
[INFO    ] Running state [/tmp/ca.crl] at time 09:47:34.218070
[INFO    ] Executing state x509.crl_managed for /tmp/ca.crl
Enter PEM pass phrase:

If i hit ctrl-c the run continues:

[ERROR   ] An exception occurred in this state: Traceback (most recent call last):
  File "/usr/lib/python2.7/site-packages/salt/state.py", line 1746, in call
    **cdata['kwargs'])
  File "/usr/lib/python2.7/site-packages/salt/loader.py", line 1702, in wrapper
    return f(*args, **kwargs)
  File "/usr/lib/python2.7/site-packages/salt/states/x509.py", line 641, in crl_managed
    signing_cert=signing_cert, revoked=revoked, days_valid=days_valid, digest=digest, include_expired=include_expired)
  File "/usr/lib/python2.7/site-packages/salt/modules/x509.py", line 975, in create_crl
    get_pem_entry(signing_private_key))
  File "/usr/lib/python2.7/site-packages/OpenSSL/crypto.py", line 2583, in load_privatekey
    _raise_current_error()
  File "/usr/lib/python2.7/site-packages/OpenSSL/_util.py", line 48, in exception_from_error_queue
    raise exception_type(errors)
Error: []

[INFO    ] Completed state [/tmp/ca.crl] at time 09:48:40.029482 duration_in_ms=65811.411
[INFO    ] Running state [/tmp/cert.crt] at time 09:48:40.030427
[INFO    ] Executing state x509.certificate_managed for /tmp/cert.crt
[INFO    ] {'Certificate': {'New': {'MD5 Finger Print': '3B:E7:29:FD:A1:3F:C5:BD:80:07:60:20:DB:14:5E:5D', 'Version': 3L, 'Key Size': 4096, 'Not After': '2017-02-25 08:48:40', 'X509v3 Extensions': OrderedDict([('basicConstraints', 'critical CA:FALSE'), ('keyUsage', 'critical Digital Signature, Key Encipherment'), ('extendedKeyUsage', 'TLS Web Server Authentication, TLS Web Client Authentication'), ('subjectKeyIdentifier', '8F:B8:B0:DF:54:2C:10:CC:25:2C:2A:78:D5:68:5C:64:16:4F:DF:BF'), ('authorityKeyIdentifier', 'keyid:8F:B8:B0:DF:54:2C:10:CC:25:2C:2A:78:D5:68:5C:64:16:4F:DF:BF\nDirName:/C=DE/CN=test.ca/L=Location/ST=ST/emailAddress=test@test.ca\nserial:C2:99:4A:50:09:6C:C3:B2\n'), ('nsComment', 'salt managed webserver CERT')]), 'Subject Hash': '54:3B:6C:A4', 'SHA1 Finger Print': 'D3:D3:8F:F3:EA:C3:CB:23:54:A9:6B:C1:56:8B:0D:C5:5C:8C:98:15', 'SHA-256 Finger Print': '24:4B:20:0C:04:D5:F6:4F:98:4E:50:10:75:51:6C:B8:84:B0:16:45:A7:74:80:53:73:8D:D1:79:9E:37:38:AC', 'Serial Number': '36:E2:25:85:C6:E4:E0:57', 'Public Key': '-----BEGIN PUBLIC KEY-----\nMIICIjANBgkqhkiG9w0BAQEFAAOCAg8AMIICCgKCAgEAq9YSjWcIF/iIawdIJi9S\nFrnYJpUr+0uwFnN+EJMln0/D8+5IVhrKeHSbcrgQWPBUXPrPODqfvqUnGbxkFphC\nvBybLzK6eF3IcsL8UMuOJjGHCQtiG8cHt3ZyKUE4OOIBRAgRqqY9swweUH+Wy3Iu\nVHac9eqfht5r+MYKY6DIsKTebLvztQ3uOPv4fGWYVHTmzUKrDFqwPgU9IsEXU7L/\np/rjb0lp2nLa71Spjdrx+km7mIHr7EohYM+rBNzba9oiuG42ihINkTJat8s7y/da\nJNA6+SrpbjqP7AFVUCCqJYVaSAALp3CqhVyner3lrhSMcGmsM1CnZKYj18CVJ+pB\njzbvYzKIX+yrzhXQISDRq1VlM4WO+pAyrea8B6VwLqn2JFNfw+J25PmSpku/mTZv\nS5rhXyvPW+HrfyrEdqIJ6G6w1jHWcT+9zFDU/J5u7jNcGQ5GeiDhVwLq5hWtoJlq\ndoAfx60h5JX5xeiLE8iwveBU/mLzR35DMhV987EliHgQltU471WctSFgwhINkPGw\nwDFUlERNp+Xwg0ondEzTD+a8hPePDqe1bzH43WoeWMH/grD2bLGGUITiq/VuFppO\nC7m4tXQwh+1y0Bib6ohnTwhV5D0yCV84x4jJ0lc+E+NvoGttRVVyVavKskhvR0RW\nsgSl/y8gOsxdpyDHmHwhMo0CAwEAAQ==\n-----END PUBLIC KEY-----\n', 'Issuer Hash': '49:E9:44:4B', 'Subject': {}, 'Not Before': '2017-01-26 08:48:40', 'Issuer': {'C': 'DE', 'SP': 'ST', 'emailAddress': 'test@test.ca', 'CN': 'test.ca', 'L': 'Location'}}, 'Old': '/tmp/cert.crt does not exist.'}}
[INFO    ] Completed state [/tmp/cert.crt] at time 09:48:40.082599 duration_in_ms=52.171

So it seems the x509.crl_managed doesn't know anything about the password.

EDIT: @clinta if i enter the password manually in the salt-call i got another error:

[INFO    ] Executing state x509.crl_managed for /tmp/ca.crl
Enter PEM pass phrase:
[DEBUG   ] LazyLoaded cmd.run_stdout
[INFO    ] Executing command 'openssl crl -text -noout -in /tmp/tmpdewb3i' in directory '/root'
[DEBUG   ] stdout: Certificate Revocation List (CRL):
        Version 1 (0x0)
    Signature Algorithm: sha256WithRSAEncryption
        Issuer: /C=DE/CN=test.ca/L=Location/ST=ST/emailAddress=test@test.ca
        Last Update: Feb  1 00:03:25 2017 GMT
        Next Update: Mar  3 00:03:25 2017 GMT
No Revoked Certificates.
    Signature Algorithm: sha256WithRSAEncryption
         8f:b0:85:4a:cf:f2:fc:8f:e4:a8:bf:26:a2:d5:de:12:e9:56:
         1b:41:d2:27:e4:54:a4:47:17:62:86:70:c7:9f:49:ff:a4:04:
         8a:2c:bd:0d:57:1f:b5:4d:9b:fa:99:07:4e:ee:8e:5e:97:fe:
         73:fc:ff:74:aa:06:55:3e:b4:f5:fa:17:a9:a1:6e:3f:3a:df:
         ea:93:e2:ae:27:c5:d4:f7:47:6e:b1:51:5d:be:ed:15:4b:1e:
         70:2c:49:0e:2f:0c:c3:8a:33:46:26:38:bc:58:44:b8:49:7b:
         ad:97:cb:95:45:88:40:a3:36:64:35:ba:1c:e6:4b:bc:17:9c:
         d1:0e:6d:7d:5d:8e:56:17:7b:9b:ad:28:92:4c:2d:9b:43:0a:
         06:5b:97:95:a4:54:1a:df:6e:58:3d:3d:df:85:96:cd:7c:b6:
         df:68:f8:e6:21:9a:e4:67:ae:8d:4d:7e:0f:45:c1:31:e5:87:
         48:d1:ca:9e:89:c5:29:a3:c7:ed:37:0a:7b:0b:0a:74:a2:38:
         a8:df:54:fb:42:72:66:3a:67:da:f0:83:00:53:37:cf:39:c9:
         69:14:bf:e3:20:56:b6:b0:fd:e1:cd:48:7a:85:79:83:d3:12:
         57:5e:66:ec:53:f4:ed:ea:15:38:dc:40:90:2d:80:be:22:6d:
         0f:cf:65:63:55:b6:ef:16:f0:a6:b8:31:e4:e6:fc:10:0d:5c:
         7a:c9:b2:70:49:95:25:67:3e:a2:1b:54:4a:88:2a:17:21:6d:
         19:fd:4a:04:d3:d5:52:80:e7:f9:58:b1:64:cf:c3:c9:22:f4:
         11:61:bc:47:93:e7:45:8d:b1:7a:b1:d8:0f:a8:2e:3a:9a:14:
         22:e7:d2:0d:f1:75:ff:db:6d:0a:65:f1:a4:53:1c:98:ca:f2:
         ad:fb:62:da:be:83:55:80:4d:d8:a4:96:24:35:ca:aa:24:a3:
         4f:52:58:29:ff:8a:b2:af:ec:15:6c:77:9c:f1:0a:3f:68:79:
         01:1d:c8:16:df:6b:17:75:fc:2c:af:8c:8b:1e:58:20:1d:fd:
         41:49:37:1f:32:c5:04:df:21:3c:3b:d2:fc:f6:9d:77:f2:58:
         bb:47:16:fa:3d:7d:26:5c:08:9a:ae:b5:5c:55:3a:81:11:b8:
         89:76:46:84:97:56:52:ae:4f:13:d0:20:b9:9a:04:c4:f9:fc:
         a0:f3:22:7e:71:de:b8:cf:07:d8:3b:bb:da:e1:47:40:35:31:
         15:7a:ac:b1:31:61:36:b6:a1:04:35:71:89:21:9b:8c:c9:e2:
         04:9d:9e:2f:28:31:45:35:16:10:77:a1:d2:28:21:46:7d:b7:
         33:bd:c5:c8:1d:f2:dd:30
[ERROR   ] An exception occurred in this state: Traceback (most recent call last):
  File "/usr/lib/python2.7/site-packages/salt/state.py", line 1746, in call
    **cdata['kwargs'])
  File "/usr/lib/python2.7/site-packages/salt/loader.py", line 1702, in wrapper
    return f(*args, **kwargs)
  File "/usr/lib/python2.7/site-packages/salt/states/x509.py", line 662, in crl_managed
    'x509.read_crl'](crl=new_crl)}
  File "/usr/lib/python2.7/site-packages/salt/modules/x509.py", line 647, in read_crl
    text = _text_or_file(crl)
  File "/usr/lib/python2.7/site-packages/salt/modules/x509.py", line 317, in _text_or_file
    if os.path.isfile(input_):
  File "/usr/lib/python2.7/genericpath.py", line 37, in isfile
    st = os.stat(path)
TypeError: coercing to Unicode: need string or buffer, bool found

[INFO    ] Completed state [/tmp/ca.crl] at time 01:03:25.330581 duration_in_ms=1909.102

Maybe that is just a follow up error as it is not the use case to provide cli user data on salt-call in this form...

MorphBonehunter commented 7 years ago

What about the csr_managed state and/or the create_csr module. Are the password stuff also needed for this?

MorphBonehunter commented 7 years ago

@clinta i've realized that your pull request was two days too late for 2011.11.2 :thinking: Anyway...did you see a chance, that the crl_managed and csr_managed stuff could be easily fixed so that the passphrase stuff is fully functional? I've testet the csr_managed part and can't get this working also:

pki_csr:
    x509.csr_managed:
        - name: /tmp/cert.csr
        - private_key: /tmp/ca.key
        - basicConstraints: "critical CA:false"
        - nsComment: "salt managed webserver CERT"
        - subjectKeyIdentifier: hash
        - authorityKeyIdentifier: keyid,issuer:always
        - extendedKeyUsage: serverAuth,clientAuth
        - keyUsage: "critical digitalSignature, keyEncipherment"
        - days_valid: 30
        - days_remaining: 5
        - backup: True
        - require:
            - x509: pki_ca_cert

fails with:

          ID: pki_csr
    Function: x509.csr_managed
        Name: /tmp/cert.csr
      Result: False
     Comment: An exception occurred in this state: Traceback (most recent call last):
                File "/usr/lib/python2.7/site-packages/salt/state.py", line 1746, in call
                  **cdata['kwargs'])
                File "/usr/lib/python2.7/site-packages/salt/loader.py", line 1702, in wrapper
                  return f(*args, **kwargs)
                File "/usr/lib/python2.7/site-packages/salt/states/x509.py", line 332, in csr_managed
                  old = __salt__['x509.read_csr'](name)
                File "/usr/lib/python2.7/site-packages/salt/modules/x509.py", line 615, in read_csr
                  csr = _get_request_obj(csr)
                File "/usr/lib/python2.7/site-packages/salt/modules/x509.py", line 380, in _get_request_obj
                  text = get_pem_entry(text, pem_type='CERTIFICATE REQUEST')
                File "/usr/lib/python2.7/site-packages/salt/modules/x509.py", line 472, in get_pem_entry
                  raise salt.exceptions.SaltInvocationError(errmsg)
              SaltInvocationError: PEM does not contain a single entry of type CERTIFICATE REQUEST:
              /tmp/cert.csr
     Started: 00:54:43.821987
    Duration: 6.33 ms
     Changes:   

I've also have problems with the consistency of private_key which is in the example but as the documentation says see above for valid properties i think it should be either signing_private_key or public_key not private_key but also with signing_private_key + signing_private_key_passphrase it does not change the outcome.

Should i open another Issue for the "change password on key" stuff as another feature request or is this the right "topic" here for digging further?

clinta commented 7 years ago

Yeah, I'm working on a fix for those two states. Should have another PR in shortly.

The changing password for a private key stuff is more involved, and I don't think I'll have time to implement, but I will add a - force option which will allow re-creating the private key if the specified passphrase does not match.

clinta commented 7 years ago

That latest PR is tested and works with the below test state covering CRLs and CSRs:

pki_private_key:
    x509.private_key_managed:
        - name: /tmp/ca.key
        - bits: 4096
        - passphrase: test
        - cipher: aes_256_cbc
        - backup: True

pki_ca_cert:
    x509.certificate_managed:
        - name: /tmp/ca.crt
        - signing_private_key: /tmp/ca.key
        - signing_private_key_passphrase: test
        - CN: test.ca
        - C: DE
        - ST: ST
        - L: Location
        - Email: test@test.ca
        - basicConstraints: "critical CA:true"
        - keyUsage: "critical cRLSign, keyCertSign"
        - subjectKeyIdentifier: hash
        - authorityKeyIdentifier: keyid,issuer:always
        - days_valid: 3650
        - days_remaining: 0
        - backup: True
        - require:
            - x509: pki_private_key

pki_crl:
    x509.crl_managed:
        - name: /tmp/ca.crl
        - signing_private_key: /tmp/ca.key
        - signing_private_key_passphrase: test
        - signing_cert: /tmp/ca.crt
        - digest: sha256
        - days_valid: 30
        - days_remaining: 5
        - backup: True
        - require:
            - x509: pki_ca_cert

pki_cert:
    x509.certificate_managed:
        - name: /tmp/cert.crt
        - signing_private_key: /tmp/ca.key
        - signing_private_key_passphrase: test
        - signing_cert: /tmp/ca.crt
        - basicConstraints: "critical CA:false"
        - nsComment: "salt managed webserver CERT"
        - subjectKeyIdentifier: hash
        - authorityKeyIdentifier: keyid,issuer:always
        - extendedKeyUsage: serverAuth,clientAuth
        - keyUsage: "critical digitalSignature, keyEncipherment"
        - days_valid: 30
        - days_remaining: 5
        - backup: True
        - require:
            - x509: pki_ca_cert

pki_csr:
    x509.csr_managed:
        - name: /tmp/cert.csr
        - private_key: /tmp/ca.key
        - private_key_passphrase: test
        - basicConstraints: "critical CA:false"
        - nsComment: "salt managed webserver CERT"
        - subjectKeyIdentifier: hash
        - authorityKeyIdentifier: keyid,issuer:always
        - extendedKeyUsage: serverAuth,clientAuth
        - keyUsage: "critical digitalSignature, keyEncipherment"
        - days_valid: 30
        - days_remaining: 5
        - backup: True
        - require:
            - x509: pki_ca_cert
clinta commented 7 years ago

And a new overwrite option has been added to private_key_managed which will allow the state to overwrite an existing private key if the provided passphrase does not decrypt it.

MorphBonehunter commented 7 years ago

I have tested this also, works now like expected. @haraldrudell: I think the original expectation of the issue is fulfilled, so maybe this could be closed and an new issue could be opened for the "change password" case, what do you think?

stale[bot] commented 6 years ago

This issue has been automatically marked as stale because it has not had recent activity. It will be closed if no further activity occurs. Thank you for your contributions.

If this issue is closed prematurely, please leave a comment and we will gladly reopen the issue.