1 /*
2  * Copyright (C) Internet Systems Consortium, Inc. ("ISC")
3  *
4  * SPDX-License-Identifier: MPL-2.0
5  *
6  * This Source Code Form is subject to the terms of the Mozilla Public
7  * License, v. 2.0. If a copy of the MPL was not distributed with this
8  * file, you can obtain one at https://mozilla.org/MPL/2.0/.
9  *
10  * See the COPYRIGHT file distributed with this work for additional
11  * information regarding copyright ownership.
12  */
13 
14 #ifndef DNS_TKEY_H
15 #define DNS_TKEY_H 1
16 
17 /*! \file dns/tkey.h */
18 
19 #include <inttypes.h>
20 #include <stdbool.h>
21 
22 #include <isc/lang.h>
23 
24 #include <dns/types.h>
25 
26 #include <dst/dst.h>
27 #include <dst/gssapi.h>
28 
29 ISC_LANG_BEGINDECLS
30 
31 /* Key agreement modes */
32 #define DNS_TKEYMODE_SERVERASSIGNED   1
33 #define DNS_TKEYMODE_DIFFIEHELLMAN    2
34 #define DNS_TKEYMODE_GSSAPI	      3
35 #define DNS_TKEYMODE_RESOLVERASSIGNED 4
36 #define DNS_TKEYMODE_DELETE	      5
37 
38 struct dns_tkeyctx {
39 	dst_key_t	  *dhkey;
40 	dns_name_t	   *domain;
41 	dns_gss_cred_id_t gsscred;
42 	isc_mem_t	  *mctx;
43 	char	     *gssapi_keytab;
44 };
45 
46 isc_result_t
47 dns_tkeyctx_create(isc_mem_t *mctx, dns_tkeyctx_t **tctxp);
48 /*%<
49  *	Create an empty TKEY context.
50  *
51  * 	Requires:
52  *\li		'mctx' is not NULL
53  *\li		'tctx' is not NULL
54  *\li		'*tctx' is NULL
55  *
56  *	Returns
57  *\li		#ISC_R_SUCCESS
58  *\li		#ISC_R_NOMEMORY
59  *\li		return codes from dns_name_fromtext()
60  */
61 
62 void
63 dns_tkeyctx_destroy(dns_tkeyctx_t **tctxp);
64 /*%<
65  *      Frees all data associated with the TKEY context
66  *
67  * 	Requires:
68  *\li		'tctx' is not NULL
69  *\li		'*tctx' is not NULL
70  */
71 
72 isc_result_t
73 dns_tkey_processquery(dns_message_t *msg, dns_tkeyctx_t *tctx,
74 		      dns_tsig_keyring_t *ring);
75 /*%<
76  *	Processes a query containing a TKEY record, adding or deleting TSIG
77  *	keys if necessary, and modifies the message to contain the response.
78  *
79  *	Requires:
80  *\li		'msg' is a valid message
81  *\li		'tctx' is a valid TKEY context
82  *\li		'ring' is a valid TSIG keyring
83  *
84  *	Returns
85  *\li		#ISC_R_SUCCESS	msg was updated (the TKEY operation succeeded,
86  *				or msg now includes a TKEY with an error set)
87  *		DNS_R_FORMERR	the packet was malformed (missing a TKEY
88  *				or KEY).
89  *\li		other		An error occurred while processing the message
90  */
91 
92 isc_result_t
93 dns_tkey_builddhquery(dns_message_t *msg, dst_key_t *key,
94 		      const dns_name_t *name, const dns_name_t *algorithm,
95 		      isc_buffer_t *nonce, uint32_t lifetime);
96 /*%<
97  *	Builds a query containing a TKEY that will generate a shared
98  *	secret using a Diffie-Hellman key exchange.  The shared key
99  *	will be of the specified algorithm (only DNS_TSIG_HMACMD5_NAME
100  *	is supported), and will be named either 'name',
101  *	'name' + server chosen domain, or random data + server chosen domain
102  *	if 'name' == dns_rootname.  If nonce is not NULL, it supplies
103  *	random data used in the shared secret computation.  The key is
104  *	requested to have the specified lifetime (in seconds)
105  *
106  *
107  *	Requires:
108  *\li		'msg' is a valid message
109  *\li		'key' is a valid Diffie Hellman dst key
110  *\li		'name' is a valid name
111  *\li		'algorithm' is a valid name
112  *
113  *	Returns:
114  *\li		#ISC_R_SUCCESS	msg was successfully updated to include the
115  *				query to be sent
116  *\li		other		an error occurred while building the message
117  */
118 
119 isc_result_t
120 dns_tkey_buildgssquery(dns_message_t *msg, const dns_name_t *name,
121 		       const dns_name_t *gname, isc_buffer_t *intoken,
122 		       uint32_t lifetime, dns_gss_ctx_id_t *context, bool win2k,
123 		       isc_mem_t *mctx, char **err_message);
124 /*%<
125  *	Builds a query containing a TKEY that will generate a GSSAPI context.
126  *	The key is requested to have the specified lifetime (in seconds).
127  *
128  *	Requires:
129  *\li		'msg'	  is a valid message
130  *\li		'name'	  is a valid name
131  *\li		'gname'	  is a valid name
132  *\li		'context' is a pointer to a valid gss_ctx_id_t
133  *			  (which may have the value GSS_C_NO_CONTEXT)
134  *\li		'win2k'   when true says to turn on some hacks to work
135  *			  with the non-standard GSS-TSIG of Windows 2000
136  *
137  *	Returns:
138  *\li		ISC_R_SUCCESS	msg was successfully updated to include the
139  *				query to be sent
140  *\li		other		an error occurred while building the message
141  *\li		*err_message	optional error message
142  */
143 
144 isc_result_t
145 dns_tkey_builddeletequery(dns_message_t *msg, dns_tsigkey_t *key);
146 /*%<
147  *	Builds a query containing a TKEY record that will delete the
148  *	specified shared secret from the server.
149  *
150  *	Requires:
151  *\li		'msg' is a valid message
152  *\li		'key' is a valid TSIG key
153  *
154  *	Returns:
155  *\li		#ISC_R_SUCCESS	msg was successfully updated to include the
156  *				query to be sent
157  *\li		other		an error occurred while building the message
158  */
159 
160 isc_result_t
161 dns_tkey_processdhresponse(dns_message_t *qmsg, dns_message_t *rmsg,
162 			   dst_key_t *key, isc_buffer_t *nonce,
163 			   dns_tsigkey_t **outkey, dns_tsig_keyring_t *ring);
164 /*%<
165  *	Processes a response to a query containing a TKEY that was
166  *	designed to generate a shared secret using a Diffie-Hellman key
167  *	exchange.  If the query was successful, a new shared key
168  *	is created and added to the list of shared keys.
169  *
170  *	Requires:
171  *\li		'qmsg' is a valid message (the query)
172  *\li		'rmsg' is a valid message (the response)
173  *\li		'key' is a valid Diffie Hellman dst key
174  *\li		'outkey' is either NULL or a pointer to NULL
175  *\li		'ring' is a valid keyring or NULL
176  *
177  *	Returns:
178  *\li		#ISC_R_SUCCESS	the shared key was successfully added
179  *\li		#ISC_R_NOTFOUND	an error occurred while looking for a
180  *				component of the query or response
181  */
182 
183 isc_result_t
184 dns_tkey_processgssresponse(dns_message_t *qmsg, dns_message_t *rmsg,
185 			    const dns_name_t *gname, dns_gss_ctx_id_t *context,
186 			    isc_buffer_t *outtoken, dns_tsigkey_t **outkey,
187 			    dns_tsig_keyring_t *ring, char **err_message);
188 /*%<
189  * XXX
190  */
191 
192 isc_result_t
193 dns_tkey_processdeleteresponse(dns_message_t *qmsg, dns_message_t *rmsg,
194 			       dns_tsig_keyring_t *ring);
195 /*%<
196  *	Processes a response to a query containing a TKEY that was
197  *	designed to delete a shared secret.  If the query was successful,
198  *	the shared key is deleted from the list of shared keys.
199  *
200  *	Requires:
201  *\li		'qmsg' is a valid message (the query)
202  *\li		'rmsg' is a valid message (the response)
203  *\li		'ring' is not NULL
204  *
205  *	Returns:
206  *\li		#ISC_R_SUCCESS	the shared key was successfully deleted
207  *\li		#ISC_R_NOTFOUND	an error occurred while looking for a
208  *				component of the query or response
209  */
210 
211 isc_result_t
212 dns_tkey_gssnegotiate(dns_message_t *qmsg, dns_message_t *rmsg,
213 		      const dns_name_t *server, dns_gss_ctx_id_t *context,
214 		      dns_tsigkey_t **outkey, dns_tsig_keyring_t *ring,
215 		      bool win2k, char **err_message);
216 
217 /*
218  *	Client side negotiation of GSS-TSIG.  Process the response
219  *	to a TKEY, and establish a TSIG key if negotiation was successful.
220  *	Build a response to the input TKEY message.  Can take multiple
221  *	calls to successfully establish the context.
222  *
223  *	Requires:
224  *		'qmsg'    is a valid message, the original TKEY request;
225  *			     it will be filled with the new message to send
226  *		'rmsg'    is a valid message, the incoming TKEY message
227  *		'server'  is the server name
228  *		'context' is the input context handle
229  *		'outkey'  receives the established key, if non-NULL;
230  *			      if non-NULL must point to NULL
231  *		'ring'	  is the keyring in which to establish the key,
232  *			      or NULL
233  *		'win2k'   when true says to turn on some hacks to work
234  *			      with the non-standard GSS-TSIG of Windows 2000
235  *
236  *	Returns:
237  *		ISC_R_SUCCESS	context was successfully established
238  *		ISC_R_NOTFOUND  couldn't find a needed part of the query
239  *					or response
240  *		DNS_R_CONTINUE  additional context negotiation is required;
241  *					send the new qmsg to the server
242  */
243 
244 ISC_LANG_ENDDECLS
245 
246 #endif /* DNS_TKEY_H */
247