#include #include #include #include #include #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 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; }