2 * Copyright (c) 2002 - 2004, Stockholms universitet
3 * (Stockholm University, Stockholm Sweden)
6 * Redistribution is not permitted
16 #include "rxgk_proto.h"
22 int rxgk_key_contrib_size = 16;
29 rxk5_mutual_auth_client_generate(krb5_context context, krb5_keyblock *key,
31 RXGK_Token *challage_token)
35 RXGK_CHALLENGE_TOKEN ct;
36 char buf[RXGK_CHALLENGE_TOKEN_MAX_SIZE];
42 ret = krb5_crypto_init (context, key, key->keytype, &crypto);
46 ct.ct_version = RXGK_CR_TOKEN_VERSION;
48 ct.ct_enctype.val = malloc(sizeof(ct.ct_enctype.val[0]));
49 ct.ct_enctype.len = 1;
50 if (ct.ct_enctype.val == NULL) {
54 ct.ct_enctype.val[0] = RXGK_CRYPTO_DES_CBC_CRC;
56 sz = RXGK_CHALLENGE_TOKEN_MAX_SIZE;
57 if (ydr_encode_RXGK_CHALLENGE_TOKEN(&ct, buf, &sz) == NULL) {
61 sz = RXGK_CHALLENGE_TOKEN_MAX_SIZE - sz;
63 ret = krb5_encrypt(context, crypto, 0, buf, sz, &data);
67 challage_token->val = malloc(data.length);
68 if (challage_token->val == NULL) {
73 challage_token->len = data.length;
74 memcpy(challage_token->val, data.data, data.length);
77 ydr_free_RXGK_CHALLENGE_TOKEN(&ct);
79 krb5_data_free(&data);
80 krb5_crypto_destroy(context, crypto);
89 rxk5_mutual_auth_client_check(krb5_context context, krb5_keyblock *key,
91 const RXGK_Token *challage_token,
92 krb5_keyblock *rxsession_key)
100 memset(&rt, 0, sizeof(rt));
101 memset(rxsession_key, 0, sizeof(*rxsession_key));
103 ret = krb5_crypto_init (context, key, key->keytype, &crypto);
109 ret = krb5_decrypt(context, crypto, 0,
110 challage_token->val, challage_token->len,
116 if (ydr_decode_RXGK_REPLY_TOKEN(&rt, data.data, &sz) == NULL) {
117 ret = RXGKSEALEDINCON;
121 if (rt.rt_nonce != number + 1) {
122 ret = RXGKSEALEDINCON;
126 if (rt.rt_error != 0) {
132 /* XXX check rt_enctype */
133 ret = rxgk_random_to_key(rt.rt_enctype,
134 rt.rt_key.val, rt.rt_key.len,
137 ret = krb5_copy_keyblock_contents(context, key, rxsession_key);
141 ydr_free_RXGK_REPLY_TOKEN(&rt);
144 krb5_data_free(&data);
145 krb5_crypto_destroy(context, crypto);
155 rxk5_mutual_auth_server(krb5_context context, krb5_keyblock *key,
156 const RXGK_Token *challage_token,
157 int *session_enctype,
158 void **session_key, size_t *session_key_size,
159 RXGK_Token *reply_token)
163 krb5_keyblock keyblock;
164 RXGK_CHALLENGE_TOKEN ct;
166 char buf[RXGK_REPLY_TOKEN_MAX_SIZE];
170 memset(&rt, 0, sizeof(rt));
171 memset(&ct, 0, sizeof(ct));
173 *session_enctype = 0;
175 *session_key_size = 0;
177 keyblock.keyvalue.data = NULL;
179 sz = RXGK_CHALLENGE_TOKEN_MAX_SIZE - sz;
181 ret = krb5_crypto_init (context, key, key->keytype, &crypto);
187 ret = krb5_decrypt(context, crypto, 0,
188 challage_token->val, challage_token->len,
194 if (ydr_decode_RXGK_CHALLENGE_TOKEN(&ct, data.data, &sz) == NULL) {
195 memset(&ct, 0, sizeof(ct));
199 sz = data.length - sz;
201 krb5_data_free(&data);
204 if (ct.ct_version < RXGK_CR_TOKEN_VERSION) {
205 ret = RXGKSEALEDINCON;
210 /* XXX choose best enctype, not just the one we use now */
214 for (i = 0; i < ct.ct_enctype.len ; i++) {
215 if (ct.ct_enctype.val[i] == key->keytype)
219 if (i == ct.ct_enctype.len)
220 ret = RXGKSEALEDINCON;
223 rt.rt_version = RXGK_CR_TOKEN_VERSION;
224 rt.rt_nonce = ct.ct_nonce + 1;
227 rt.rt_key.val = NULL;
231 ret = krb5_generate_random_keyblock(context,
235 rt.rt_enctype = keyblock.keytype;
236 rt.rt_key.len = keyblock.keyvalue.length;
237 rt.rt_key.val = keyblock.keyvalue.data;
239 *session_enctype = keyblock.keytype;
240 *session_key_size = keyblock.keyvalue.length;
241 *session_key = malloc(keyblock.keyvalue.length);
242 if (*session_key == NULL)
244 memcpy(*session_key, keyblock.keyvalue.data,
245 keyblock.keyvalue.length);
251 sz = RXGK_REPLY_TOKEN_MAX_SIZE;
252 if (ydr_encode_RXGK_REPLY_TOKEN(&rt, buf, &sz) == 0) {
256 sz = RXGK_REPLY_TOKEN_MAX_SIZE - sz;
258 memset(rt.rt_key.val, 0, rt.rt_key.len);
261 ret = krb5_encrypt(context, crypto, 0, buf, sz, &data);
265 reply_token->val = malloc(data.length);
266 if (reply_token->val == NULL) {
271 reply_token->len = data.length;
272 memcpy(reply_token->val, data.data, data.length);
275 ydr_free_RXGK_CHALLENGE_TOKEN(&ct);
276 /* ydr_free_RXGK_REPLY_TOKEN(&rt); */
279 krb5_data_free(&data);
280 if (keyblock.keyvalue.data)
281 krb5_free_keyblock_contents(context, &keyblock);
282 krb5_crypto_destroy(context, crypto);
291 rxgk_getheader(struct rx_packet *pkt, struct rxgk_header_data *h)
295 /* Collect selected packet fields */
296 h->call_number = htonl(pkt->header.callNumber);
297 t = ((pkt->header.cid & RX_CHANNELMASK) << (32 - RX_CIDSHIFT))
298 | ((pkt->header.seq & 0x3fffffff));
299 h->channel_and_seq = htonl(t);
308 rxgk_derive_transport_key(krb5_context context,
309 krb5_keyblock *rx_conn_key,
310 RXGK_rxtransport_key *keycontrib,
315 /* XXX heimdal broken doesn't implement derive key for des encrypes */
317 switch (rx_conn_key->keytype) {
318 case RXGK_CRYPTO_DES_CBC_CRC:
319 case RXGK_CRYPTO_DES_CBC_MD4:
320 case RXGK_CRYPTO_DES_CBC_MD5:
321 ret = krb5_copy_keyblock_contents(context, rx_conn_key, rkey);
327 char rxk_enc[RXGK_RXTRANSPORT_KEY_MAX_SIZE];
331 sz = RXGK_RXTRANSPORT_KEY_MAX_SIZE;
332 if (ydr_encode_RXGK_rxtransport_key(keycontrib, rxk_enc, &sz) == NULL)
335 sz = RXGK_RXTRANSPORT_KEY_MAX_SIZE - sz;
337 ret = krb5_derive_key (context,
339 rx_conn_key->keytype,
346 ret = krb5_copy_keyblock_contents(context, key, rkey);
350 krb5_free_keyblock(context, key);
367 rxgk_random_to_key(int enctype,
368 void *random_data, int random_sz,
371 memset(key, 0, sizeof(*key));
374 case RXGK_CRYPTO_DES_CBC_CRC:
375 case RXGK_CRYPTO_DES_CBC_MD4:
376 case RXGK_CRYPTO_DES_CBC_MD5:
378 return RXGKINCONSISTENCY;
381 return RXGKINCONSISTENCY;
384 key->keyvalue.data = malloc(random_sz);
385 if (key->keyvalue.data == NULL)
387 memcpy(key->keyvalue.data, random_data, random_sz);
388 key->keyvalue.length = random_sz;
389 key->keytype = enctype;