SHA256
1
0
forked from pool/krb5
krb5/EncryptWithMasterKey.c

216 lines
5.6 KiB
C

#include <com_err.h>
#include <krb5.h>
#include <stdio.h>
#include <string.h>
#include <errno.h>
#define krb5_kdb_decode_int16(cp, i16) \
*((krb5_int16 *) &(i16)) = (((krb5_int16) ((unsigned char) (cp)[0]))| \
((krb5_int16) ((unsigned char) (cp)[1]) << 8))
#define encode_int16(i16, cp) \
{ \
(cp)[0] = (unsigned char) ((i16) & 0xff); \
(cp)[1] = (unsigned char) (((i16) >> 8) & 0xff); \
}
krb5_error_code
krb5_db_fetch_mkey(krb5_context context,
krb5_enctype etype,
char *keyfile,
krb5_keyblock * key)
{
krb5_error_code retval;
/* from somewhere else */
krb5_ui_2 enctype;
FILE *kf;
retval = 0;
key->magic = KV5M_KEYBLOCK;
if (!(kf = fopen(keyfile, "r")))
return KRB5_KDB_CANTREAD_STORED;
if (fread((krb5_pointer) &enctype, 2, 1, kf) != 1) {
retval = KRB5_KDB_CANTREAD_STORED;
goto errout;
}
if (key->enctype == ENCTYPE_UNKNOWN)
key->enctype = enctype;
else if (enctype != key->enctype) {
retval = KRB5_KDB_BADSTORED_MKEY;
goto errout;
}
if (fread((krb5_pointer) &key->length,
sizeof(key->length), 1, kf) != 1) {
retval = KRB5_KDB_CANTREAD_STORED;
goto errout;
}
if (!key->length || ((int) key->length) < 0) {
retval = KRB5_KDB_BADSTORED_MKEY;
goto errout;
}
if (!(key->contents = (krb5_octet *)malloc(key->length))) {
retval = ENOMEM;
goto errout;
}
if (fread((krb5_pointer) key->contents,
sizeof(key->contents[0]), key->length, kf)
!= key->length) {
retval = KRB5_KDB_CANTREAD_STORED;
memset(key->contents, 0, key->length);
free(key->contents);
key->contents = 0;
} else
retval = 0;
errout:
(void) fclose(kf);
return retval;
}
static int
read_octet_string(char *str, krb5_octet *buf, size_t len)
{
int c;
int i, retval;
char *s;
s = str;
retval = 0;
for (i=0; i<len; i++) {
if (sscanf(s, "%02x", &c) != 1) {
retval = 1;
free(s);
break;
}
buf[i] = (krb5_octet) c;
if(i+1 < len) {
s++;
s++;
}
}
s = NULL;
return(retval);
}
void usage()
{
fprintf(stderr, "Usage: "
"EncryptWithMasterKey -sf stashfilename -d data [-e enctype]\n"
"\t [-sf stashfilename] \n"
"\t [-d the data to encrypt]\n"
"\t [-e encryption type of the master key] (default des3-cbc-sha1)\n\n"
"\t valid enctypes are:\n\n"
"\t des-cbc-crc, des-cbc-md4, des-cbc-md5, des, des-cbc-raw,\n"
"\t des3-cbc-raw, des3-cbc-sha1, des3-hmac-sha1, des3-cbc-sha1-kd,\n"
"\t des-hmac-sha1, arcfour-hmac, rc4-hmac, arcfour-hmac-md5,\n"
"\t arcfour-hmac-exp, rc4-hmac-exp, arcfour-hmac-md5-exp,\n"
"\t aes128-cts-hmac-sha1-96, aes128-cts, aes256-cts-hmac-sha1-96,\n"
"\t aes256-cts\n");
exit(1);
}
#define ARG_VAL (--argc > 0 ? (koptarg = *(++argv)) : (char *)(usage(), NULL))
int main(int argc, char *argv[])
{
krb5_context context;
krb5_error_code retval;
krb5_keyblock master_keyblock;
krb5_data plain;
krb5_enc_data cipher;
size_t plainlen = 0;
size_t enclen = 0;
char *koptarg;
char *stashfile = NULL;
char *data = NULL;
int i = 0;
master_keyblock.enctype = ENCTYPE_DES3_CBC_SHA1;
argv++; argc--;
while (*argv) {
if (strcmp(*argv, "-sf") == 0 && ARG_VAL) {
stashfile = koptarg;
} else if (strcmp(*argv, "-d") == 0 && ARG_VAL) {
data = koptarg;
} else if (strcmp(*argv, "-e") == 0 && ARG_VAL) {
if (krb5_string_to_enctype(koptarg, &master_keyblock.enctype))
{
com_err(argv[0], 0, "%s is an invalid enctype", koptarg);
usage();
}
} else {
usage();
}
argv++; argc--;
}
if (data == NULL || stashfile == NULL)
usage();
retval = krb5_init_context(&context);
if( retval )
{
com_err(argv[0], retval, "while initializing krb5_context");
exit(1);
}
retval = krb5_db_fetch_mkey(context,
master_keyblock.enctype,
stashfile,
&master_keyblock);
if( retval )
{
com_err(argv[0], retval, "while fetching master key");
exit(1);
}
plainlen = strlen(data)/2;
plain.data = (char *) malloc(plainlen);
plain.length = plainlen;
read_octet_string(data, (krb5_octet*)plain.data, plainlen);
retval = krb5_c_encrypt_length(context,
master_keyblock.enctype,
plain.length, &enclen);
if( retval )
{
com_err(argv[0], retval, "while calculating cipher data length");
exit(1);
}
cipher.ciphertext.data = (char *) malloc(enclen);
cipher.ciphertext.length = enclen;
retval = krb5_c_encrypt(context, &master_keyblock, /* XXX */ 0, 0,
&plain, &cipher);
if( retval )
{
com_err(argv[0], retval, "while encrypting data");
exit(1);
}
/* first print out the length of the decrypted hash */
char l[2];
encode_int16((unsigned int)plainlen, l);
printf("%02x%02x", l[0], l[1]);
/* now print the encrypted key */
for(i = 0; i < cipher.ciphertext.length; ++i)
{
printf("%02x",(unsigned char)cipher.ciphertext.data[i]);
}
printf("\n");
return 0;
}