1 /*
2  * Copyright (c) 1999, 2010, Oracle and/or its affiliates. All rights reserved.
3  */
4 
5 
6 /*
7  * Copyright (C) 1998 by the FundsXpress, INC.
8  *
9  * All rights reserved.
10  *
11  * Export of this software from the United States of America may require
12  * a specific license from the United States Government.  It is the
13  * responsibility of any person or organization contemplating export to
14  * obtain such a license before exporting.
15  *
16  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
17  * distribute this software and its documentation for any purpose and
18  * without fee is hereby granted, provided that the above copyright
19  * notice appear in all copies and that both that copyright notice and
20  * this permission notice appear in supporting documentation, and that
21  * the name of FundsXpress. not be used in advertising or publicity pertaining
22  * to distribution of the software without specific, written prior
23  * permission.  FundsXpress makes no representations about the suitability of
24  * this software for any purpose.  It is provided "as is" without express
25  * or implied warranty.
26  *
27  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
28  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
29  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
30  */
31 
32 #include "k5-int.h"
33 #include "etypes.h"
34 #include <locale.h>
35 
36 krb5_error_code KRB5_CALLCONV
krb5_c_make_random_key(krb5_context context,krb5_enctype enctype,krb5_keyblock * random_key)37 krb5_c_make_random_key(krb5_context context, krb5_enctype enctype,
38 		       krb5_keyblock *random_key)
39 {
40     int i;
41     krb5_error_code ret;
42     const struct krb5_enc_provider *enc;
43     size_t keybytes, keylength;
44     krb5_data random_data;
45     unsigned char *bytes;
46 
47     for (i=0; i<krb5_enctypes_length; i++) {
48 	if (krb5_enctypes_list[i].etype == enctype)
49 	    break;
50     }
51 
52     /* Solaris Kerberos: Better error message */
53     if (i == krb5_enctypes_length) {
54 	krb5_set_error_message(context, KRB5_BAD_ENCTYPE,
55 			    dgettext(TEXT_DOMAIN,
56 				    "Unknown encryption type: %d"),
57 			    enctype);
58 	return(KRB5_BAD_ENCTYPE);
59     }
60 
61     enc = krb5_enctypes_list[i].enc;
62 
63     keybytes = enc->keybytes;
64     keylength = enc->keylength;
65 
66     if ((bytes = (unsigned char *) malloc(keybytes)) == NULL)
67 	return(ENOMEM);
68     if ((random_key->contents = (krb5_octet *) malloc(keylength)) == NULL) {
69 	free(bytes);
70 	return(ENOMEM);
71     }
72 
73     random_data.data = (char *) bytes;
74     random_data.length = keybytes;
75 
76     if ((ret = krb5_c_random_make_octets(context, &random_data)))
77 	goto cleanup;
78 
79     random_key->magic = KV5M_KEYBLOCK;
80     random_key->enctype = enctype;
81     random_key->length = keylength;
82 
83     /* Solaris Kerberos */
84     random_key->dk_list = NULL;
85 #ifdef _KERNEL
86     random_key->kef_key = NULL;
87 #else
88     random_key->hKey = CK_INVALID_HANDLE;
89 #endif
90 
91     /* Solaris Kerberos */
92     ret = ((*(enc->make_key))(context, &random_data, random_key));
93 
94 cleanup:
95     memset(bytes, 0, keybytes);
96     free(bytes);
97 
98     if (ret) {
99 	memset(random_key->contents, 0, keylength);
100 	free(random_key->contents);
101 	/* Solaris Kerberos */
102 	random_key->contents = NULL;
103     }
104 
105     return(ret);
106 }
107