1 /*
2  * Copyright 2008 Sun Microsystems, Inc.  All rights reserved.
3  * Use is subject to license terms.
4  */
5 
6 
7 /*
8  * Copyright (C) 1998 by the FundsXpress, INC.
9  *
10  * All rights reserved.
11  *
12  * Export of this software from the United States of America may require
13  * a specific license from the United States Government.  It is the
14  * responsibility of any person or organization contemplating export to
15  * obtain such a license before exporting.
16  *
17  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
18  * distribute this software and its documentation for any purpose and
19  * without fee is hereby granted, provided that the above copyright
20  * notice appear in all copies and that both that copyright notice and
21  * this permission notice appear in supporting documentation, and that
22  * the name of FundsXpress. not be used in advertising or publicity pertaining
23  * to distribution of the software without specific, written prior
24  * permission.  FundsXpress makes no representations about the suitability of
25  * this software for any purpose.  It is provided "as is" without express
26  * or implied warranty.
27  *
28  * THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR
29  * IMPLIED WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED
30  * WARRANTIES OF MERCHANTIBILITY AND FITNESS FOR A PARTICULAR PURPOSE.
31  */
32 
33 #include "dk.h"
34 
35 static const unsigned char kerberos[] = "kerberos";
36 #define kerberos_len (sizeof(kerberos)-1)
37 
38 krb5_error_code
krb5int_dk_string_to_key(krb5_context context,const struct krb5_enc_provider * enc,const krb5_data * string,const krb5_data * salt,const krb5_data * parms,krb5_keyblock * key)39 krb5int_dk_string_to_key(
40 			 krb5_context context,
41 			 const struct krb5_enc_provider *enc,
42 			 const krb5_data *string, const krb5_data *salt,
43 			 const krb5_data *parms, krb5_keyblock *key)
44 {
45     krb5_error_code ret;
46     size_t keybytes, keylength, concatlen;
47     unsigned char *concat, *foldstring, *foldkeydata;
48     krb5_data indata;
49     krb5_keyblock foldkey;
50 
51     /* key->length is checked by krb5_derive_key */
52 
53     keybytes = enc->keybytes;
54     keylength = enc->keylength;
55 
56     concatlen = string->length+(salt?salt->length:0);
57 
58     if ((concat = (unsigned char *) malloc(concatlen)) == NULL)
59 	return(ENOMEM);
60     if ((foldstring = (unsigned char *) malloc(keybytes)) == NULL) {
61 	free(concat);
62 	return(ENOMEM);
63     }
64     if ((foldkeydata = (unsigned char *) malloc(keylength)) == NULL) {
65 	free(foldstring);
66 	free(concat);
67 	return(ENOMEM);
68     }
69 
70     /* construct input string ( = string + salt), fold it, make_key it */
71 
72     memcpy(concat, string->data, string->length);
73     if (salt)
74 	memcpy(concat+string->length, salt->data, salt->length);
75 
76     krb5_nfold(concatlen*8, concat, keybytes*8, foldstring);
77 
78     indata.length = keybytes;
79     indata.data = (char *) foldstring;
80 
81     /* Solaris Kerberos */
82     memset(&foldkey, 0, sizeof (krb5_keyblock));
83     foldkey.enctype = key->enctype;
84     foldkey.length = keylength;
85     foldkey.contents = foldkeydata;
86 
87     /* Solaris Kerberos */
88     (*(enc->make_key))(context, &indata, &foldkey);
89 
90     /* now derive the key from this one */
91 
92     indata.length = kerberos_len;
93     indata.data = (char *) kerberos;
94     /* Solaris Kerberos */
95     if ((ret = krb5_derive_key(context, enc, &foldkey, key, &indata)))
96 	(void) memset(key->contents, 0, key->length);
97 
98     /* ret is set correctly by the prior call */
99 
100     memset(concat, 0, concatlen);
101     memset(foldstring, 0, keybytes);
102     memset(foldkeydata, 0, keylength);
103 
104     free(foldkeydata);
105     free(foldstring);
106     free(concat);
107 
108     return(ret);
109 }
110