Vistassja Williams (132944w)
2019-Jan-13 16:36 UTC
Questions about OpenSSH public key authentication details
Good day, I'm a Computer Science Honours student doing a thesis in which I want to add a new feature to OpenSSH (specifically, version 7.9). I've read the authentication protocol for SSH (RFC 4252) several times but I'm having trouble figuring out exactly how the SSH client communicates with the SSH server in OpenSSH during public key authentication. According to the PROTOCOL document in the OpenSSH package, there are no deviations from the authentication protocol spelled out in the document I mentioned before. I am hoping there is someone on this mailing list that can enlighten me on some of my questions. The second paragraph in Section 7 (Public Key Authentication Method: "publickey") of RFC 4252 says: "With this method, the possession of a private key serves as authentication. This method works by sending a signature created with a private key of the user. The server MUST check that the key is a valid authenticator for the user, and MUST check that the signature is valid. If both hold, the authentication request MUST be accepted; otherwise, it MUST be rejected. Note that the server MAY require additional authentications after successful authentication." I understand that the SSH authentication protocol is just a guideline that provides a higher level explanation of what should happen during authentication. Is there anyone here who can provide me with a detailed description of how authentication occurs once both the ssh client and the server start communicating? (A link or copy of a document describing this would be fine.) I can find high-level descriptions of the protocol in RFC 4252, and slightly more detailed explanations in postings such as https://security.stackexchange.com/questions/9366/ssh-public-private-key-pair/9389, although there are variations between postings I find on-line, which hinders my understanding of the details. On the other hand, I can obviously read through the code to find out exactly what OpenSSH is doing. However, making the jump from the very high-level descriptions to the code is proving difficult, and I was hoping to get some insight by finding out some more details from sources which are authoritative (hopefully people on this mailing list). For example, the PROTOCOL file says "The server MUST check that the key is a valid authenticator for the user". *Exactly how*, in OpenSSH, does the server check that the key is a valid authenticator? It also says "The server MUST check that the signature is valid..." but it does not say exactly what data is signed. That is, what specific data is hashed (presumably) by which hash function? My main issue in understanding the protocol is that I would like a more in-depth and clear explanation of what exactly is going on behind the scenes in OpenSSH. There are many sources on forums, but they all have varying answers that never say exactly the same thing. This understanding would greatly assist me in my thesis project. Thank you for your time, Vistassja Williams
Damien Miller
2019-Jan-17 03:52 UTC
Questions about OpenSSH public key authentication details
On Sun, 13 Jan 2019, Vistassja Williams (132944w) wrote:> Good day, > > I'm a Computer Science Honours student doing a thesis in which I want > to add a new feature to OpenSSH (specifically, version 7.9). I've > read the authentication protocol for SSH (RFC 4252) several > times but I'm having trouble figuring out exactly how the SSH client > communicates with the SSH server in OpenSSH during public key > authentication. According to the PROTOCOL document in the OpenSSH > package, there are no deviations from the authentication protocol > spelled out in the document I mentioned before. I am hoping there is > someone on this mailing list that can enlighten me on some of my questions. > > The second paragraph in Section 7 (Public Key Authentication Method: > "publickey") of RFC 4252 says: > > "With this method, the possession of a private key serves as > authentication. This method works by sending a signature created with > a private key of the user. The server MUST check that the key is a > valid authenticator for the user, and MUST check that the signature is > valid. If both hold, the authentication request MUST be accepted; > otherwise, it MUST be rejected. Note that the server MAY require > additional authentications after successful authentication." > > I understand that the SSH authentication protocol is just a > guideline that provides a higher level explanation of what should > happen during authentication. Is there anyone here who can provide me > with a detailed description of how authentication occurs once both the > ssh client and the server start communicating? (A link or copy of a > document describing this would be fine.) > > I can find high-level descriptions of the protocol in RFC 4252, and > slightly more detailed explanations in postings such as > https://security.stackexchange.com/questions/9366/ssh-public-private-key-pair/9389, > although there are variations between postings I find on-line, which > hinders my understanding of the details. On the other hand, I can > obviously read through the code to find out exactly what OpenSSH is > doing. However, making the jump from the very high-level descriptions > to the code is proving difficult, and I was hoping to get some insight > by finding out some more details from sources which are authoritative > (hopefully people on this mailing list). > > For example, the PROTOCOL file says "The server MUST check that the > key is a valid authenticator for the user". *Exactly how*, in > OpenSSH, does the server check that the key is a valid authenticator?In OpenSSH publickey auth is implemented in auth2-pubkey.c's userauth_pubkey() function and the flow is pretty easy to read. The authorization specific part is in the user_key_allowed() function. It's a little less of a linear read, but still fairly straightforward: 1. Check whether the key (and the CA key too in the case of a certificate) is revoked. Fail if it is. 2. If the key is a certificate, then check is against any trusted CA keys specified via TrustedUserCAKeys. If the CA isn't trusted then fail. 2a. If the certificate's CA is trusted, then apply any specified certificate -> principals mapping specified by via the AuthorizedPrincipalsFile or AuthorizedPrincipalsCommand directives. If the principals in the certificate are accepted then return success. 3. Try to match the key in the output of an AuthorizedKeysCommand program if one was specified in sshd_config. If it matches, then return success. 4. Try to match the key against all specified AuthorizedKeysFiles specified in sshd_config. If it matches then return success. 5. Otherwise return failure. (this is a summary and skips a few steps, e.g. authorized keys option processing).> It also says "The server MUST check that the signature is valid..." > but it does not say exactly what data is signed. That is, what > specific data is hashed (presumably) by which hash function?The RFC does say what data is signed:> Ylonen & Lonvick Standards Track [Page 9] > RFC 4252 SSH Authentication Protocol January 2006 > > The value of 'signature' is a signature by the corresponding private > key over the following data, in the following order: > > string session identifier > byte SSH_MSG_USERAUTH_REQUEST > string user name > string service name > string "publickey" > boolean TRUE > string public key algorithm name > string public key to be used for authenticationThe hash function is specified for each public key algorithm, e.g. in RFC4253 for ssh-rsa and ssh-dss (TLDR it's SHA1), in RFC5656 for ecdsa-sha2-* and in https://tools.ietf.org/html/draft-ietf-curdle-ssh-curves-08 for the curve25519-sha256 algorithm. Hope this helps. -d