]> git.proxmox.com Git - ceph.git/blame - ceph/doc/dev/session_authentication.rst
add subtree-ish sources for 12.0.3
[ceph.git] / ceph / doc / dev / session_authentication.rst
CommitLineData
7c673cae
FG
1==============================================
2Session Authentication for the Cephx Protocol
3==============================================
4Peter Reiher
57/30/12
6
7The original Cephx protocol authenticated the client to the authenticator and set up a session
8key used to authenticate the client to the server it needs to talk to. It did not, however,
9authenticate the ongoing messages between the client and server. Based on the fact that they
10share a secret key, these ongoing session messages can be easily authenticated by using the
11key to sign the messages.
12
13This document describes changes to the code that allow such ongoing session authentication.
14The changes allow for future changes that permit other authentication protocols (and the
15existing null NONE and UNKNOWN protocols) to handle signatures, but the only protocol that
16actually does signatures, at the time of the writing, is the Cephx protocol.
17
18Introduction
19-------------
20
21This code comes into play after the Cephx protocol has completed. At this point, the client and
22server share a secret key. This key will be used for authentication. For other protocols, there
23may or may not be such a key in place, and perhaps the actual procedures used to perform
24signing will be different, so the code is written to be general.
25
26The "session" here is represented by an established pipe. For such pipes, there should be a
27``session\_security`` structure attached to the pipe. Whenever a message is to be sent on the
28pipe, code that handles the signature for this kind of session security will be called. On the
29other end of the pipe, code that checks this kind of session security's message signatures will
30be called. Messages that fail the signature check will not be processed further. That implies
31that the sender had better be in agreement with the receiver on the session security being used,
32since otherwise messages will be uniformly dropped between them.
33
34The code is also prepared to handle encryption and decryption of session messages, which would
35add secrecy to the integrity provided by the signatures. No protocol currently implemented
36encrypts the ongoing session messages, though.
37
38For this functionality to work, several steps are required. First, the sender and receiver must have
39a successful run of the cephx protocol to establish a shared key. They must store that key somewhere
40that the pipe can get at later, to permit messages to be signed with it. Sent messages must be
41signed, and received messages must have their signatures checked.
42
43The signature could be computed in a variety of ways, but currently its size is limited to 64 bits.
44A message's signature is placed in its footer, in a field called ``sig``.
45
46The signature code in Cephx can be turned on and off at runtime, using a Ceph boolean option called
47``cephx\_sign\_messages``. It is currently set to false, by default, so no messages will be signed. It
48must be changed to true to cause signatures to be calculated and checked.
49
50Storing the Key
51---------------
52
53The key is needed to create signatures on the sending end and check signatures on the receiving end.
54In the future, if asymmetric crypto is an option, it's possible that two keys (a private one for
55this end of the pipe and a public one for the other end) would need to be stored. At this time,
56messages going in both directions will be signed with the same key, so only that key needs to be
57saved.
58
59The key is saved when the pipe is established. On the client side, this happens in ``connect()``,
60which is located in ``msg/Pipe.cc``. The key is obtained from a run of the Cephx protocol,
61which results in a successfully checked authorizer structure. If there is such an authorizer
62available, the code calls ``get\_auth\_session\_handler()`` to create a new authentication session handler
63and stores it in the pipe data structure. On the server side, a similar thing is done in
64``accept()`` after the authorizer provided by the client has been verified.
65
66Once these things are done on either end of the connection, session authentication can start.
67
68These routines (``connect()`` and ``accept()``) are also used to handle situations where a new
69session is being set up. At this stage, no authorizer has been created yet, so there's no key.
70Special cases in the code that calls the signature code skip these calls when the
71``CEPH\_AUTH\_UNKNOWN`` protocol is in use. This protocol label is on the pre-authorizer
72messages in a session, indicating that negotiation on an authentication protocol is ongoing and
73thus signature is not possible. There will be a reliable authentication operation later in this
74session before anything sensitive should be passed, so this is not a security problem.
75
76Signing Messages
77----------------
78
79Messages are signed in the ``write\_message`` call located in ``msg/Pipe.cc``. The actual
80signature process is to encrypt the CRCs for the message using the shared key. Thus, we must
81defer signing until all CRCs have been computed. The header CRC is computed last, so we
82call ``sign\_message()`` as soon as we've calculated that CRC.
83
84``sign\_message()`` is a virtual function defined in ``auth/AuthSessionHandler.h``. Thus,
85a specific version of it must be written for each authentication protocol supported. Currently,
86only UNKNOWN, NONE and CEPHX are supported. So there is a separate version of ``sign\_message()`` in
87``auth/unknown/AuthUnknownSessionHandler.h``, ``auth/none/AuthNoneSessionHandler.h`` and
88``auth/cephx/CephxSessionHandler.cc``. The UNKNOWN and NONE versions simply return 0, indicating
89success.
90
91The CEPHX version is more extensive. It is found in ``auth/cephx/CephxSessionHandler.cc``.
92The first thing done is to determine if the run time option to handle signatures (see above) is on.
93If not, the Cephx version of ``sign\_message()`` simply returns success without actually calculating
94a signature or inserting it into the message.
95
96If the run time option is enabled, ``sign\_message()`` copies all of the message's CRCs (one from the
97header and three from the footer) into a buffer. It calls ``encode\_encrypt()`` on the buffer,
98using the key obtained from the pipe's ``session\_security`` structure. 64 bits of the encrypted
99result are put into the message footer's signature field and a footer flag is set to indicate that
100the message was signed. (This flag is a sanity check. It is not regarded as definitive
101evidence that the message was signed. The presence of a ``session\_security`` structure at the
102receiving end requires a signature regardless of the value of this flag.) If this all goes well,
103``sign\_message()`` returns 0. If there is a problem anywhere along the line and no signature
104was computed, it returns ``SESSION\_SIGNATURE\_FAILURE``.
105
106Checking Signatures
107-------------------
108
109The signature is checked by a routine called ``check\_message\_signature()``. This is also a
110virtual function, defined in ``auth/AuthSessionHandler.h``. So again there are specific versions
111for supported authentication protocols, such as UNKNOWN, NONE and CEPHX. Again, the UNKNOWN and
112NONE versions are stored in ``auth/unknown/AuthUnknownSessionHandler.h`` and
113``auth/none/AuthNoneSessionHandler.h``, respectively, and again they simply return 0, indicating
114success.
115
116The CEPHX version of ``check\_message\_signature()`` performs a real signature check. This routine
117(stored in ``auth/cephx/CephxSessionHandler.cc``) exits with success if the run time option has
118disabled signatures. Otherwise, it takes the CRCs from the header and footer, encrypts the result,
119and compares it to the signature stored in the footer. Since an earlier routine has checked that
120the CRCs actually match the contents of the message, it is unnecessary to recompute the CRCs
121on the raw data in the message. The encryption is performed with the same ``encode\_encrypt()``
122routine used on the sending end, using the key stored in the local ``session\_security``
123data structure.
124
125If everything checks out, the CEPHX routine returns 0, indicating succcess. If there is a
126problem, the routine returns ``SESSION\_SIGNATURE\_FAILURE``.
127
128Adding New Session Authentication Methods
129-----------------------------------------
130
131For the purpose of session authentication only (not the basic authentication of client and
132server currently performed by the Cephx protocol), in addition to adding a new protocol, that
133protocol must have a ``sign\_message()`` routine and a ``check\_message\_signature`` routine.
134These routines will take a message pointer as a parameter and return 0 on success. The procedure
135used to sign and check will be specific to the new method, but probably there will be a
136``session\_security`` structure attached to the pipe that contains a cryptographic key. This
137structure will be either an ``AuthSessionHandler`` (found in ``auth/AuthSessionHandler.h``)
138or a structure derived from that type.
139
140Adding Encryption to Sessions
141-----------------------------
142
143The existing code is partially, but not fully, set up to allow sessions to have their packets
144encrypted. Part of adding encryption would be similar to adding a new authentication method.
145But one would also need to add calls to the encryption and decryption routines in ``write\_message()``
146and ``read\_message()``. These calls would probably go near where the current calls for
147authentication are made. You should consider whether you want to replace the existing calls
148with something more general that does whatever the chosen form of session security requires,
149rather than explicitly saying ``sign`` or ``encrypt``.
150
151Session Security Statistics
152---------------------------
153
154The existing Cephx authentication code keeps statistics on how many messages were signed, how
155many message signature were checked, and how many checks succeeded and failed. It is prepared
156to keep similar statistics on encryption and decryption. These statistics can be accessed through
157the call ``printAuthSessionHandlerStats`` in ``auth/AuthSessionHandler.cc``.
158
159If new authentication or encryption methods are added, they should include code that keeps these
160statistics.