Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[Bug]: Provisioner password prompt embezzles [ #955

Open
0xab-c0de opened this issue Jun 2, 2023 · 6 comments
Open

[Bug]: Provisioner password prompt embezzles [ #955

0xab-c0de opened this issue Jun 2, 2023 · 6 comments
Assignees
Labels
bug needs triage Waiting for discussion / prioritization by team

Comments

@0xab-c0de
Copy link

Steps to Reproduce

  1. JWT provisioner pki-admin with a random password containing a [
  2. On a windows client, in PowerShell:
step ca certificate --issuer=pki-admin --san=this.domain.com --san=this this.domain.com this.crt this.key

Output:

✔ Provisioner: pki-admin (JWK) [kid: asdf]
Please enter the password to decrypt the provisioner key: ☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺
Please enter the password to decrypt the provisioner key: ☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺
failed to decrypt JWE: invalid password

The [ char is not captured by the step-cli prompt in PowerShell.

  1. Change the provisioner password to match a plain ASCII string ([a-z][A-Z][0-9]); based on https://smallstep.com/docs/step-ca/provisioners/#changing-a-jwk-provisioner-password

  2. Repeat 2.

Output:

✔ Provisioner: pki-admin (JWK) [kid: asdf]
Please enter the password to decrypt the provisioner key: ☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺
✔ CA: https://my.step.url:443
✔ Would you like to overwrite this.crt [y/n]: y
✔ Would you like to overwrite this.key [y/n]: y
✔ Certificate: this.crt
✔ Private Key: this.key

Your Environment

  • Server OS - Alpine Linux v3.18
  • step-ca Version - Smallstep CA/0.24.2 (linux/arm64)
  • Client OS - Windows 11 21H2 (Build 22000.2003)
  • step Version - Smallstep CLI/0.24.1 (windows/amd64)

Step CA

compose service name is: ca

$ docker compose exec -it ca cat /etc/os-release
NAME="Alpine Linux"
ID=alpine
VERSION_ID=3.18.0
PRETTY_NAME="Alpine Linux v3.18"
HOME_URL="https://alpinelinux.org/"
BUG_REPORT_URL="https://gitlab.alpinelinux.org/alpine/aports/-/issues"

$ docker compose exec -it ca step --version
Smallstep CLI/0.24.4 (linux/arm64)
Release Date: 2023-05-11 19:53 UTC

$ docker compose exec -it ca step-ca --version
Smallstep CA/0.24.2 (linux/arm64)
Release Date: 2023-05-11 20:16 UTC

Windows Client

Installed via winget

PS C:\Users\me> step version
Smallstep CLI/0.24.1 (windows/amd64)
Release Date: 2023-04-12T21:56:42Z

Manual usage of 0.24.4:

PS C:\Users\me\Downloads\step_0.24.4\bin> .\step version
Smallstep CLI/0.24.4 (windows/amd64)
Release Date: 2023-05-11T19:52:34Z

Expected Behavior

Provisioner password prompt receives every character as-is when copy/paste from password manager tool.

Actual Behavior

Provisioner password prompt embezzles [.

Additional Context

OS language: en-us
Keyboard layout: de-ch

I assume it's an issue in the Go prompt. In powershell.exe or cmd.exe you'll see these when entering the password. When typing a [ manually, it isn't captured by the prompt. A password with l=32 results in effective l=30.

Contributing

Vote on this issue by adding a 👍 reaction.
To contribute a fix for this issue, leave a comment (and link to your pull request, if you've opened one already).

@0xab-c0de 0xab-c0de added bug needs triage Waiting for discussion / prioritization by team labels Jun 2, 2023
@maraino
Copy link
Collaborator

maraino commented Jun 2, 2023

I've tried to reproduce this with an older Windows 10 VM, using the latest version of PowerShell, but I'm not able to do it.

Can you reproduce this with other commands, for example combining these two:

step crypto jwk create pub.jwk priv.jwk
step crypto key format priv.jwk

Or just trying to use step crypto key format with the key you already have.

@0xab-c0de
Copy link
Author

Thanks for your reply @maraino

I've tested the step crypto commands.

Situation is the same. (It behaves equally in powershell - running in the windows terminal - and in the integrated posh console of vscode).

Password choosen for the below example: asdf[123 - i copy/paste the password string from text editor to the prompt. The echo in the prompt is only 4 chars instead of 8.

PS C:\Users\me> step crypto jwk create pub.jwk priv.jwk
Please enter the password to encrypt the private JWK: ☺☺☺☺
Your public key has been saved in pub.jwk.
Your private key has been saved in priv.jwk.
PS C:\Users\me>

As long, as i copy/paste, it can work, as the chars captured by the prompt are the same and match, so decryption is possible.

PS C:\Users\me> step crypto key format priv.jwk
Please enter the password to decrypt the key: ☺☺☺☺          # <- pasted the same asdf[123
Please enter the password to encrypt the private key: ☺☺☺   # <- 123 provided
-----BEGIN EC PRIVATE KEY-----
Proc-Type: 4,ENCRYPTED
DEK-Info: AES-256-CBC,eda476e094a9c7fc976ac2fee0d445f4

m3CJRC5IH6t2AcSOV0W37q4Z798BWDajlRAwJCDDoal/DYJ7vKf8K4x2DgNmzbzi
...
UiZBRivEX+EGavDZY1v4jg/MBRhxvr2nvdYemrUUC8o=
-----END EC PRIVATE KEY-----```

I made some more examples on the same machine.

More examples on the provisioners

My ca is started as container in the background:

# start the container with https:8443 and http:8442, name it "myca"
docker run -d --rm --name myca -v step-ca_step:/home/step -p 8443:8443 -p 8442:8442 smallstep/step-ca

Example test3: create a provisioner test3 with a generated password

Note: The password contains again a [

PS C:\Users\me> docker exec -it myca step ca provisioner add test3 --type=JWK --create=true
Please enter a password to encrypt the provisioner private key? [leave empty and we'll generate one]:
✔ Password: 6%`Kj0Xu)6C'mQn7WfU7q38Fs>;a[ah,█
✔ CA Configuration: /home/step/config/ca.json

Success! Your `step-ca` config has been updated. To pick up the new configuration SIGHUP (kill -1 <pid>) or restart the step-ca process.
PS C:\Users\me> 
PS C:\Users\me> 
PS C:\Users\me> 
PS C:\Users\me> docker container restart myca
myca
PS C:\Users\me> 
PS C:\Users\me> 
PS C:\Users\me> 
PS C:\Users\me> step ca certificate --issuer=test3 --san=foo.domain.com --san=foo foo.domain.com foo.crt foo.key
✔ Provisioner: test3 (JWK) [kid: OMMwfPsYkez0TXgDX0DxPM2Nv-SFxk-L7Gv4bu1tvm8]
Please enter the password to decrypt the provisioner key: ☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺
Please enter the password to decrypt the provisioner key: ☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺
Please enter the password to decrypt the provisioner key: ☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺
failed to decrypt JWE: invalid password
PS C:\Users\me>

Example test4: add provisioner test4 with generated password

Note: The password does not contain a [

PS C:\Users\me> docker exec -it myca step ca provisioner add test4 --type=JWK --create=true
Please enter a password to encrypt the provisioner private key? [leave empty and we'll generate one]:
✔ Password: AJ#Ibndg1<+O_)j^Yw:u;U(#-0\c;(N>
✔ CA Configuration: /home/step/config/ca.json

Success! Your `step-ca` config has been updated. To pick up the new configuration SIGHUP (kill -1 <pid>) or restart the step-ca process.   
PS C:\Users\me> 
PS C:\Users\me> 
PS C:\Users\me> docker container restart myca
myca
PS C:\Users\me>
PS C:\Users\me>
PS C:\Users\me> step ca certificate --issuer=test4 --san=foo.domain.com --san=foo foo.domain.com foo.crt foo.key
✔ Provisioner: test4 (JWK) [kid: gvbo8lpUM0ICUeEYVwnhE2T6NXXsWEgfRT2IXwFQyjI]
Please enter the password to decrypt the provisioner key: ☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺
✔ CA: https://localhost:8443
✔ Certificate: foo.crt
✔ Private Key: foo.key
PS C:\Users\me> 

Example test5: add provisioner test5 entering a password containing [ - see the note below the example.

Note : i used the password of test3 and pasted manually into the containers prompt. Afterwards, when issuing the cert on windows, the situation will occur and it doesn't match to be able to decrypt the provisioner key.
The linux prompt of step ca provisioner add can capture the [.
The windows prompt of step xx can't - or better - does not.

PS C:\Users\me> docker exec -it myca step ca provisioner add test5 --type=JWK --create=true
Please enter a password to encrypt the provisioner private key? [leave empty and we'll generate one]: ☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺     
✔ CA Configuration: /home/step/config/ca.json

Success! Your `step-ca` config has been updated. To pick up the new configuration SIGHUP (kill -1 <pid>) or restart the step-ca process.   
PS C:\Users\me>
PS C:\Users\me> docker container restart myca
myca
PS C:\Users\me>
PS C:\Users\me>
PS C:\Users\me> step ca certificate --issuer=test5 --san=baz.domain.com --san=baz baz.domain.com baz.crt baz.key   
✔ Provisioner: test5 (JWK) [kid: FYb4nC-G316IIEg-jVqakP5SsOGn-t8ieyJl60Yq7ns]
Please enter the password to decrypt the provisioner key: ☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺
Please enter the password to decrypt the provisioner key: ☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺
Please enter the password to decrypt the provisioner key: ☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺
failed to decrypt JWE: invalid password
PS C:\Users\me>
entered: ☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺    (copied from console)
echoed : ☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺☺      (copied from console - 2 chars missing)

I'll try to reproduce it on another machine with almost identical setup.

@maraino
Copy link
Collaborator

maraino commented Jun 5, 2023

I've tried on a Windows 11 VM on Azure, and I could still use a key with the password "asdf[123". But I noticed one thing, doing echo "asdf[123" > pass.txt and trying to decode with pass.txt failed. The reason was that the file was written using UTF-16 instead of just ASCII or UTF-8, they are equivalent for this case. So I wonder if this can be related, although your case looked different as you see less .

Our step-kms-plugin reads the password using a different method. If you compile the version in main and do this, you should see the public key:

step crypto keypair --password-file password.txt pub.pem priv.pem
step-kms-plugin key softkms:priv.pem

Where password.txt is encoded in ASCII/UTF-8, and step-kms-plugin is compiled from the main branch, this will not work on the last released version.

@maraino
Copy link
Collaborator

maraino commented Jun 6, 2023

I suppose this works step ca certificate --provisioner-password-file pass.txt ..., right?

@0xab-c0de
Copy link
Author

@maraino

I've tried on a Windows 11 VM on Azure, and I could still use a key with the password "asdf[123". But I noticed one thing, doing echo "asdf[123" > pass.txt and trying to decode with pass.txt failed. The reason was that the file was written using UTF-16 instead of just ASCII or UTF-8, they are equivalent for this case. So I wonder if this can be related, although your case looked different as you see less .

Our step-kms-plugin reads the password using a different method. If you compile the version in main and do this, you should see the public key:

step crypto keypair --password-file password.txt pub.pem priv.pem
step-kms-plugin key softkms:priv.pem

Where password.txt is encoded in ASCII/UTF-8, and step-kms-plugin is compiled from the main branch, this will not work on the last released version.

Result:
The step-kms-plugin approach looks good. I used the password of my test 3.

PS C:\Users\me\local\step-kms-plugin> step crypto keypair --password-file .\pw.txt pub.pem priv.pem
Your public key has been saved in pub.pem.
Your private key has been saved in priv.pem.
PS C:\Users\me\local\step-kms-plugin> .\step-kms-plugin.exe key softkms:priv.pem
-----BEGIN PUBLIC KEY-----
MFkwEwYHKoZIzj0CAQYIKoZIzj0DAQcDQgAEOK1J/vgAhxeMutOa8YMnspvuu2mM
Dzq4SjieFUnCQBQT65HgMkuVgoYgYITXj2rlWbpJT21yUAq7d8w6Rh7cvw==
-----END PUBLIC KEY-----
PS C:\Users\me\local\step-kms-plugin>

I suppose this works step ca certificate --provisioner-password-file pass.txt ..., right?

Result:

The --password-file works, with encoding ascii || utf8.

PS C:\Users\me> step ca certificate --issuer=test3 --password-file .\pw.txt --san=foo.domain.com --san=foo foo.domain.com foo.crt foo.key
✔ Provisioner: test3 (JWK) [kid: OMMwfPsYkez0TXgDX0DxPM2Nv-SFxk-L7Gv4bu1tvm8]
✔ CA: https://localhost:8443
✔ Would you like to overwrite foo.crt [y/n]: y
✔ Would you like to overwrite foo.key [y/n]: y
✔ Certificate: foo.crt
✔ Private Key: foo.key

@0xab-c0de
Copy link
Author

@maraino

It's the input language setting of Windows 11.

There are two input languages on my system now.

PS C:\Users\me> Get-WinUserLanguageList


LanguageTag     : de-CH
Autonym         : Deutsch (Schweiz)
EnglishName     : German
LocalizedName   : German (Switzerland)
ScriptName      : Latin
InputMethodTips : {0807:00000807}
Spellchecking   : True
Handwriting     : False

LanguageTag     : en-US
Autonym         : English (United States)
EnglishName     : English
LocalizedName   : English (United States)
ScriptName      : Latin
InputMethodTips : {0409:00000409}
Spellchecking   : True
Handwriting     : False

Start a powershell:

PS C:\Users\me> Add-Type -AssemblyName System.Windows.Forms
PS C:\Users\me> [System.Windows.Forms.InputLanguage]::CurrentInputLanguage

Culture   Handle LayoutName
-------   ------ ----------
en-US   67699721 US


PS C:\Users\me>
PS C:\Users\me> step ca certificate --issuer=test3 --san=foo.domain.com --san=foo foo.domain.com foo.crt foo.key
✔ Provisioner: test3 (JWK) [kid: OMMwfPsYkez0TXgDX0DxPM2Nv-SFxk-L7Gv4bu1tvm8]
Please enter the password to decrypt the provisioner key: ��������������������������������
✔ CA: https://localhost:8443
✔ Would you like to overwrite foo.crt [y/n]: y
✔ Would you like to overwrite foo.key [y/n]: y
✔ Certificate: foo.crt
✔ Private Key: foo.key
PS C:\Users\me>exit

Change the input language with WIN+SPACE.

Start a new powershell:

PS C:\Users\me> Add-Type -AssemblyName System.Windows.Forms
PS C:\Users\me> [System.Windows.Forms.InputLanguage]::CurrentInputLanguage

Culture    Handle LayoutName
-------    ------ ----------
de-CH   134678535 Swiss German


PS C:\Users\me> step ca certificate --issuer=test3 --san=foo.domain.com --san=foo foo.domain.com foo.crt foo.key
✔ Provisioner: test3 (JWK) [kid: OMMwfPsYkez0TXgDX0DxPM2Nv-SFxk-L7Gv4bu1tvm8]
Please enter the password to decrypt the provisioner key: ������������������������������
Please enter the password to decrypt the provisioner key: ������������������������������
Please enter the password to decrypt the provisioner key: ������������������������������
failed to decrypt JWE: invalid password
PS C:\Users\me>

The tests with step-kms-plugin (of my last post) has been done using de-ch and was successful. I repeated it after this finding. The method you're using in step-kms-plugin is independent to the input language.

@maraino maraino transferred this issue from smallstep/certificates Jun 8, 2023
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug needs triage Waiting for discussion / prioritization by team
Projects
None yet
Development

No branches or pull requests

2 participants