1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License, Version 1.0 only 6 * (the "License"). You may not use this file except in compliance 7 * with the License. 8 * 9 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 10 * or http://www.opensolaris.org/os/licensing. 11 * See the License for the specific language governing permissions 12 * and limitations under the License. 13 * 14 * When distributing Covered Code, include this CDDL HEADER in each 15 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 16 * If applicable, add the following below this CDDL HEADER, with the 17 * fields enclosed by brackets "[]" replaced with your own identifying 18 * information: Portions Copyright [yyyy] [name of copyright owner] 19 * 20 * CDDL HEADER END 21 */ 22 /* 23 * dh_gssapi.h 24 * 25 * Copyright (c) 1997, by Sun Microsystems, Inc. 26 * All rights reserved. 27 * 28 */ 29 30 #ifndef _DH_GSSAPI_H_ 31 #define _DH_GSSAPI_H_ 32 33 #pragma ident "%Z%%M% %I% %E% SMI" 34 35 #ifdef __cplusplus 36 extern "C" { 37 #endif 38 39 #include <stdio.h> 40 #include <stdlib.h> 41 #include <string.h> 42 #include <gssapi/gssapi.h> 43 #include <mechglueP.h> 44 #include <rpc/rpc.h> 45 #include <time.h> 46 #include <thread.h> 47 #include <synch.h> 48 #include "error.h" 49 #include "token.h" 50 #include "oid.h" 51 #include "crypto.h" 52 53 #define New(T, n) ((T *)calloc(n, sizeof (T))) 54 #define Free(p) free(p) 55 56 #define DH_NO_SECRETKEY 1 57 #define DH_NO_NETNAME 2 58 #define DH_VALIDATE_FAILURE 3 59 60 #define DH_MECH_QOP 0 61 62 /* 63 * This structure defines the necessary operations that a mechanism 64 * must provide for key management. 65 */ 66 typedef struct keyopts_desc { 67 /* 68 * This function pointer will encrypt the set of supplied session keys 69 * with this principal and a remote principal. For algorithm 0 70 * A common key is used, that is calculated using the classic 71 * Diffie-Hellman key exchange. An RSA style algorithm would encrypt 72 * the session key with the public key of the remote. 73 */ 74 int (*key_encryptsessions)(const char *remotename, 75 des_block deskeys[], int no_keys); 76 /* 77 * This function decrypts the set of session keys from remote. It 78 * is the inverse of the above entry point. The last parameter 79 * is an in/out parameter. If it is non-zero going in, it allows 80 * the underlying mechanism to get the public key for the remote 81 * out of a cache. If it is zero, it indicates that the mechanism 82 * should get a definitive copy of the public key because it may 83 * have changed. When returning from the entry point *key_cached 84 * will be set to non zero if the session keys were decrypted using 85 * a cached public key, otherwise zero will be return. Most mechanism 86 * will not need/want this and will always return *key_cached as zero. 87 */ 88 int (*key_decryptsessions)(const char *remotename, 89 des_block deskeys[], int no_keys, int *key_cached); 90 /* 91 * This entry point is used to generate a block of session keys 92 */ 93 int (*key_gendeskeys)(des_block *deskeys, int no_keys); 94 /* 95 * This entry point is used to see if the principal's credentials 96 * are available. 97 */ 98 int (*key_secretkey_is_set)(void); 99 /* 100 * This entry point will return the netname of the calling principal. 101 */ 102 char *(*get_principal)(void); 103 } dh_keyopts_desc, *dh_keyopts_t; 104 105 /* 106 * Diffie-Hellman principal names are just null terminated charater strings 107 * that are ONC RPC netnames. 108 */ 109 typedef char *dh_principal; 110 111 /* Diffie-Hellman credentials */ 112 typedef struct dh_cred_id_desc { 113 uid_t uid; /* The uid of this principal */ 114 gss_cred_usage_t usage; /* How this cred can be used */ 115 dh_principal principal; /* RPC netname */ 116 time_t expire; /* When this cred expires */ 117 } dh_cred_id_desc, *dh_cred_id_t; 118 119 120 /* 121 * This is the structure that defines the mechanism specific context. 122 * This allows a common backend to support a faimily of mechanism that 123 * use different key lengths and algorithms. We know the particular mechanism 124 * by that mechanism on initialization filling in the OID for that mechanaism 125 * and suppling a set of keyopts that correspond to the key length and 126 * algorithm used. 127 */ 128 typedef struct dh_context_desc { 129 gss_OID mech; 130 dh_keyopts_t keyopts; 131 } dh_context_desc, *dh_context_t; 132 133 134 /* This defines the size of the history for replay and out-of-seq detection */ 135 #define SSIZE 4 136 typedef unsigned long long seq_word_t; 137 138 /* 139 * This structure holds the state for replay and detection. It contains the 140 * bit array of the last seqence numbers that have been seen and the last 141 * sequence number. The 0th bit represents the last sequence number receive. 142 * The state contained in this structure in protected by a mutext so that 143 * multiple threads can manipulate the history. 144 */ 145 typedef struct { 146 mutex_t seq_arr_lock; /* lock on this structure */ 147 seq_word_t arr[SSIZE]; /* Bit array of sequence history */ 148 OM_uint32 seqno; /* Last seqno seen */ 149 } seq_array, *seq_array_t; 150 151 152 typedef enum { INCOMPLETE, ESTABLISHED, BAD } DHState; 153 154 /* 155 * The Diffie-Hellman context that corresponds to the gss_ctx_id_t. 156 */ 157 typedef struct dh_gss_context_desc { 158 DHState state; /* Context state */ 159 int initiate; /* 1 intiates, 0 accepts */ 160 int proto_version; /* DH protocol version */ 161 dh_principal remote; /* Netname of remote */ 162 dh_principal local; /* Netname of local */ 163 int no_keys; /* Number of session keys (currently 3) */ 164 des_block *keys; /* The session keys */ 165 OM_uint32 flags; /* GSS context flags */ 166 seq_array hist; /* Out-of-sequence, replay history */ 167 mutex_t seqno_lock; /* Lock to protect next_seqno */ 168 OM_uint32 next_seqno; /* Next seqno to send */ 169 time_t expire; /* When this context expires */ 170 int debug; /* Turn on debuging if non zero */ 171 } dh_gss_context_desc, *dh_gss_context_t; 172 173 174 /* declarations of internal name mechanism functions */ 175 176 gss_mechanism 177 __dh_generic_initialize(gss_mechanism, gss_OID_desc, dh_keyopts_t); 178 179 /* 180 * The following routines are the entry points that libgss uses. 181 * The have the same signature as the corresponding libgss functions 182 * except they are passed an additinal first parameter that is a pointer 183 * to the mechanaism specific context. In our case that void pointer is 184 * actually pointing to a dh_context. See <gssapi/gssapi.h> or the 185 * draft-ietf_cat_gssv2-cbind document for an explanation of the parameters. 186 */ 187 OM_uint32 188 __dh_gss_acquire_cred(void *, OM_uint32*, gss_name_t, OM_uint32, gss_OID_set, 189 gss_cred_usage_t, gss_cred_id_t *, gss_OID_set *, OM_uint32 *); 190 191 OM_uint32 192 __dh_gss_release_cred(void *, OM_uint32 *, gss_cred_id_t *); 193 194 OM_uint32 195 __dh_gss_init_sec_context(void *, OM_uint32 *, gss_cred_id_t, gss_ctx_id_t *, 196 gss_name_t, gss_OID, OM_uint32, OM_uint32, gss_channel_bindings_t, 197 gss_buffer_t, gss_OID *, gss_buffer_t, OM_uint32 *, OM_uint32 *); 198 199 OM_uint32 200 __dh_gss_accept_sec_context(void *, OM_uint32 *, gss_ctx_id_t *, gss_cred_id_t, 201 gss_buffer_t, gss_channel_bindings_t, gss_name_t *, gss_OID *, 202 gss_buffer_t, OM_uint32 *, OM_uint32 *, gss_cred_id_t *); 203 204 OM_uint32 205 __dh_gss_process_context_token(void *, OM_uint32 *, 206 gss_ctx_id_t, gss_buffer_t); 207 208 OM_uint32 209 __dh_gss_delete_sec_context(void *, OM_uint32 *, gss_ctx_id_t *, gss_buffer_t); 210 211 OM_uint32 212 __dh_gss_context_time(void *, OM_uint32 *, gss_ctx_id_t, OM_uint32 *); 213 214 OM_uint32 215 __dh_gss_sign(void *, OM_uint32 *, gss_ctx_id_t, 216 int, gss_buffer_t, gss_buffer_t); 217 218 OM_uint32 219 __dh_gss_verify(void *, OM_uint32 *, gss_ctx_id_t, 220 gss_buffer_t, gss_buffer_t, int *); 221 222 OM_uint32 223 __dh_gss_seal(void *, OM_uint32 *, gss_ctx_id_t, 224 int, int, gss_buffer_t, int *, gss_buffer_t); 225 226 OM_uint32 227 __dh_gss_unseal(void *, OM_uint32 *, gss_ctx_id_t, 228 gss_buffer_t, gss_buffer_t, int *, int *); 229 230 OM_uint32 231 __dh_gss_display_status(void *, OM_uint32 *, OM_uint32, 232 int, gss_OID, OM_uint32 *, gss_buffer_t); 233 234 OM_uint32 235 __dh_gss_indicate_mechs(void *, OM_uint32 *, gss_OID_set *); 236 237 OM_uint32 238 __dh_gss_compare_name(void *, OM_uint32 *, gss_name_t, gss_name_t, int *); 239 240 OM_uint32 241 __dh_gss_display_name(void *, OM_uint32 *, 242 gss_name_t, gss_buffer_t, gss_OID *); 243 244 OM_uint32 245 __dh_gss_import_name(void *, OM_uint32 *, gss_buffer_t, gss_OID, gss_name_t *); 246 247 OM_uint32 248 __dh_gss_release_name(void *, OM_uint32 *, gss_name_t *); 249 250 OM_uint32 251 __dh_gss_inquire_cred(void *, OM_uint32 *, gss_cred_id_t, gss_name_t *, 252 OM_uint32 *, gss_cred_usage_t *, gss_OID_set *); 253 254 OM_uint32 255 __dh_gss_inquire_context(void *, OM_uint32 *, gss_ctx_id_t, gss_name_t *, 256 gss_name_t *, OM_uint32 *, gss_OID *, OM_uint32 *, int *, int *); 257 258 /* New V2 entry points */ 259 OM_uint32 260 __dh_gss_get_mic(void *, OM_uint32 *, gss_ctx_id_t, 261 gss_qop_t, gss_buffer_t, gss_buffer_t); 262 263 OM_uint32 264 __dh_gss_verify_mic(void *, OM_uint32 *, gss_ctx_id_t, gss_buffer_t, 265 gss_buffer_t, gss_qop_t *); 266 267 OM_uint32 268 __dh_gss_wrap(void *, OM_uint32 *, gss_ctx_id_t, int, gss_qop_t, 269 gss_buffer_t, int *, gss_buffer_t); 270 271 OM_uint32 272 __dh_gss_unwrap(void *, OM_uint32 *, gss_ctx_id_t, gss_buffer_t, 273 gss_buffer_t, int *, gss_qop_t *); 274 275 OM_uint32 276 __dh_gss_wrap_size_limit(void *, OM_uint32 *, gss_ctx_id_t, int, 277 gss_qop_t, OM_uint32, OM_uint32 *); 278 279 OM_uint32 280 __dh_gss_import_name_object(void *, OM_uint32 *, 281 void *, gss_OID, gss_name_t *); 282 283 OM_uint32 284 __dh_gss_export_name_object(void *, OM_uint32 *, gss_name_t, gss_OID, void **); 285 286 OM_uint32 287 __dh_gss_add_cred(void *, OM_uint32 *, gss_cred_id_t, gss_name_t, gss_OID, 288 gss_cred_usage_t, OM_uint32, OM_uint32, gss_cred_id_t *, gss_OID_set *, 289 OM_uint32 *, OM_uint32 *); 290 291 OM_uint32 292 __dh_gss_inquire_cred_by_mech(void *, OM_uint32 *, gss_cred_id_t, gss_OID, 293 gss_name_t *, OM_uint32 *, OM_uint32 *, gss_cred_usage_t *); 294 295 OM_uint32 296 __dh_gss_export_sec_context(void *, OM_uint32 *, gss_ctx_id_t *, gss_buffer_t); 297 298 OM_uint32 299 __dh_gss_import_sec_context(void *, OM_uint32 *, gss_buffer_t, gss_ctx_id_t *); 300 301 OM_uint32 302 __dh_gss_internal_release_oid(void *, OM_uint32 *, gss_OID *); 303 304 OM_uint32 305 __dh_gss_inquire_names_for_mech(void *, OM_uint32 *, gss_OID, gss_OID_set *); 306 307 /* Principal to uid mapping */ 308 OM_uint32 309 __dh_pname_to_uid(void *ctx, OM_uint32 *minor, 310 const gss_name_t pname, uid_t *uid); 311 312 OM_uint32 313 __dh_gss_export_name(void *ctx, OM_uint32 *minor, 314 const gss_name_t input_name, gss_buffer_t exported_name); 315 316 /* ====================== End of libgss entry points ======================= */ 317 318 /* Routines to validate, install and remove contexts and credentials */ 319 OM_uint32 320 __dh_validate_context(dh_gss_context_t); 321 322 OM_uint32 323 __dh_install_context(dh_gss_context_t); 324 325 OM_uint32 326 __dh_remove_context(dh_gss_context_t); 327 328 OM_uint32 329 __dh_validate_cred(dh_cred_id_t); 330 331 OM_uint32 332 __dh_install_cred(dh_cred_id_t); 333 334 OM_uint32 335 __dh_remove_cred(dh_cred_id_t); 336 337 OM_uint32 338 __dh_validate_principal(dh_principal); 339 340 /* Routines for out-of-sequence and replay detection */ 341 OM_uint32 __dh_seq_detection(dh_gss_context_t, OM_uint32); 342 343 OM_uint32 __dh_next_seqno(dh_gss_context_t ctx); 344 345 void __dh_init_seq_hist(dh_gss_context_t); 346 347 void __dh_destroy_seq_hist(dh_gss_context_t ctx); 348 349 #ifdef __cplusplus 350 } 351 #endif 352 353 #endif /* _DH_GSSAPI_H_ */ 354