int shishi_apreq_decrypt (Shishi * handle, Shishi_asn1 apreq, Shishi_key * key, int keyusage, Shishi_asn1 * authenticator) { int res; int i; char *buf; size_t buflen; char *cipher; size_t cipherlen; int etype; res = shishi_apreq_get_authenticator_etype (handle, apreq, &etype); if (res != SHISHI_OK) return res; if (etype != shishi_key_type (key)) return SHISHI_APREQ_BAD_KEYTYPE; res = shishi_asn1_read (handle, apreq, "authenticator.cipher", &cipher, &cipherlen); if (res != SHISHI_OK) return res; res = shishi_decrypt (handle, key, keyusage, cipher, cipherlen, &buf, &buflen); free (cipher); if (res != SHISHI_OK) { shishi_error_printf (handle, "decrypt fail, most likely wrong password\n"); return SHISHI_APREQ_DECRYPT_FAILED; } /* The crypto is so 1980; no length indicator. Trim off pad bytes until we can parse it. */ for (i = 0; i < 8; i++) { if (VERBOSEASN1 (handle)) printf ("Trying with %d pad in enckdcrep...\n", i); *authenticator = shishi_der2asn1_authenticator (handle, &buf[0], buflen - i); if (*authenticator != NULL) break; } if (*authenticator == NULL) { shishi_error_printf (handle, "Could not DER decode Authenticator. " "Password probably correct (decrypt ok) though\n"); return SHISHI_ASN1_ERROR; } return SHISHI_OK; }
/** * shishi_tgs_req_build: * @tgs: structure that holds information about TGS exchange * * Checksum data in authenticator and add ticket and authenticator to * TGS-REQ. * * Return value: Returns SHISHI_OK iff successful. **/ int shishi_tgs_req_build (Shishi_tgs * tgs) { uint32_t apoptions; int res; if (VERBOSE (tgs->handle)) printf ("Building TGS-REQ...\n"); res = shishi_kdcreq_build (tgs->handle, tgs->tgsreq); if (res != SHISHI_OK) return res; res = shishi_apreq_options (tgs->handle, shishi_ap_req (tgs->ap), &apoptions); if (res != SHISHI_OK) { shishi_error_printf (tgs->handle, "Could not get AP-REQ AP-Options: %s\n", shishi_strerror (res)); return res; } res = shishi_ap_set_tktoptionsasn1usage (tgs->ap, tgs->tgtkt, apoptions, tgs->tgsreq, "req-body", SHISHI_KEYUSAGE_TGSREQ_APREQ_AUTHENTICATOR_CKSUM, SHISHI_KEYUSAGE_TGSREQ_APREQ_AUTHENTICATOR); if (res == SHISHI_OK) res = shishi_ap_req_build (tgs->ap); if (res != SHISHI_OK) { shishi_error_printf (tgs->handle, "Could not make AP-REQ: %s\n", shishi_strerror (res)); return res; } if (VERBOSE (tgs->handle)) printf ("Got AP-REQ...\n"); if (VERBOSEASN1 (tgs->handle)) shishi_apreq_print (tgs->handle, stdout, shishi_ap_req (tgs->ap)); res = shishi_kdcreq_add_padata_tgs (tgs->handle, tgs->tgsreq, shishi_ap_req (tgs->ap)); if (res != SHISHI_OK) { shishi_error_printf (tgs->handle, "Could not add AP-REQ to TGS: %s\n", shishi_strerror (res)); return res; } return SHISHI_OK; }
/** * shishi_tgs: * @handle: shishi handle as allocated by shishi_init(). * @tgs: holds pointer to newly allocate Shishi_tgs structure. * * Allocate a new TGS exchange variable. * * Return value: Returns SHISHI_OK iff successful. **/ int shishi_tgs (Shishi * handle, Shishi_tgs ** tgs) { Shishi_tgs *ltgs; int res; *tgs = xcalloc (1, sizeof (**tgs)); ltgs = *tgs; ltgs->handle = handle; ltgs->tgsreq = shishi_tgsreq (handle); if (ltgs->tgsreq == NULL) { shishi_error_printf (handle, "Could not create TGS-REQ: %s\n", shishi_error (handle)); return SHISHI_ASN1_ERROR; } ltgs->tgsrep = shishi_tgsrep (handle); if (ltgs->tgsreq == NULL) { shishi_error_printf (handle, "Could not create TGS-REP: %s\n", shishi_error (handle)); return SHISHI_ASN1_ERROR; } ltgs->krberror = shishi_krberror (handle); if (ltgs->krberror == NULL) { shishi_error_printf (handle, "Could not create KRB-ERROR: %s\n", shishi_error (handle)); return SHISHI_ASN1_ERROR; } res = shishi_ap_nosubkey (handle, <gs->ap); if (res != SHISHI_OK) return res; res = shishi_authenticator_remove_subkey (handle, shishi_ap_authenticator (ltgs->ap)); if (res != SHISHI_OK) return res; res = shishi_tkt (handle, <gs->tkt); if (res != SHISHI_OK) return res; return SHISHI_OK; }
int shishi_kdcreq_build (Shishi * handle, Shishi_asn1 kdcreq) { int res; size_t n; int msgtype; shishi_verbose (handle, "Building KDC-REQ..."); if (shishi_asn1_empty_p (handle, kdcreq, "req-body.rtime")) { res = shishi_asn1_write (handle, kdcreq, "req-body.rtime", NULL, 0); if (res != SHISHI_OK) { shishi_error_printf (handle, "Could not write rtime\n"); return res; } } if (shishi_asn1_empty_p (handle, kdcreq, "req-body.from")) { res = shishi_asn1_write (handle, kdcreq, "req-body.from", NULL, 0); if (res != SHISHI_OK) { shishi_error_printf (handle, "Could not write from\n"); return res; } } res = shishi_asn1_read_integer (handle, kdcreq, "msg-type", &msgtype); if (res != SHISHI_OK) return res; if (msgtype == SHISHI_MSGTYPE_AS_REQ) { res = shishi_asn1_number_of_elements (handle, kdcreq, "padata", &n); if (res == SHISHI_OK && n == 0) { res = shishi_kdcreq_clear_padata (handle, kdcreq); if (res != SHISHI_OK) { shishi_error_printf (handle, "Could not write padata\n"); return res; } } } return SHISHI_OK; }
/** * shishi_tgs_rep_process: * @tgs: structure that holds information about TGS exchange * * Process new TGS-REP and set ticket. The key to decrypt the TGS-REP * is taken from the EncKDCRepPart of the TGS tgticket. * * Return value: Returns SHISHI_OK iff successful. **/ int shishi_tgs_rep_process (Shishi_tgs * tgs) { Shishi_asn1 kdcreppart, ticket; int res; if (VERBOSE (tgs->handle)) printf ("Processing TGS-REQ and TGS-REP...\n"); res = shishi_tgs_process (tgs->handle, tgs->tgsreq, tgs->tgsrep, shishi_ap_authenticator (tgs->ap), shishi_tkt_enckdcreppart (tgs->tgtkt), &kdcreppart); if (res != SHISHI_OK) { shishi_error_printf (tgs->handle, "Could not process TGS: %s", shishi_strerror (res)); return res; } if (VERBOSE (tgs->handle)) printf ("Got EncKDCRepPart...\n"); if (VERBOSEASN1 (tgs->handle)) shishi_enckdcreppart_print (tgs->handle, stdout, kdcreppart); res = shishi_kdcrep_get_ticket (tgs->handle, tgs->tgsrep, &ticket); if (res != SHISHI_OK) { shishi_error_printf (tgs->handle, "Could not extract ticket from TGS-REP: %s", shishi_strerror (res)); return res; } if (VERBOSE (tgs->handle)) printf ("Got Ticket...\n"); if (VERBOSEASN1 (tgs->handle)) shishi_ticket_print (tgs->handle, stdout, ticket); /* XXX */ tgs->tkt = shishi_tkt2 (tgs->handle, ticket, kdcreppart, tgs->tgsrep); return SHISHI_OK; }
/** * shishi_apreq_add_authenticator: * @handle: shishi handle as allocated by shishi_init(). * @apreq: AP-REQ to add authenticator field to. * @key: key to to use for encryption. * @keyusage: cryptographic key usage value to use in encryption. * @authenticator: authenticator as allocated by shishi_authenticator(). * * Encrypts DER encoded authenticator using key and store it in the * AP-REQ. * * Return value: Returns SHISHI_OK iff successful. **/ int shishi_apreq_add_authenticator (Shishi * handle, Shishi_asn1 apreq, Shishi_key * key, int keyusage, Shishi_asn1 authenticator) { int res; char *buf; size_t buflen; char *der; size_t derlen; res = shishi_asn1_to_der (handle, authenticator, &der, &derlen); if (res != SHISHI_OK) { shishi_error_printf (handle, "Could not DER encode authenticator: %s\n", shishi_strerror (res)); return res; } res = shishi_encrypt (handle, key, keyusage, der, derlen, &buf, &buflen); free (der); if (res != SHISHI_OK) { shishi_error_printf (handle, "Cannot encrypt authenticator.\n"); return res; } res = shishi_apreq_set_authenticator (handle, apreq, shishi_key_type (key), shishi_key_version (key), buf, buflen); return res; }
/** * shishi_tgs_set_realm: * @tgs: structure that holds information about TGS exchange * @realm: indicates the realm to acquire ticket for. * * Set the server in the TGS-REQ. * * Return value: Returns SHISHI_OK iff successful. **/ int shishi_tgs_set_realm (Shishi_tgs * tgs, const char *realm) { int res; res = shishi_kdcreq_set_realm (tgs->handle, tgs->tgsreq, realm); if (res != SHISHI_OK) { shishi_error_printf (tgs->handle, "Could not set realm in KDC-REQ: %s\n", shishi_strerror (res)); return res; } return SHISHI_OK; }
/** * shishi_kdcreq_add_padata_tgs: * @handle: shishi handle as allocated by shishi_init(). * @kdcreq: KDC-REQ to add PA-DATA to. * @apreq: AP-REQ to add as PA-DATA. * * Add TGS pre-authentication data to KDC-REQ. The data is an AP-REQ * that authenticates the request. This functions simply DER encodes * the AP-REQ and calls shishi_kdcreq_add_padata() with a * SHISHI_PA_TGS_REQ padatatype. * * Return value: Returns SHISHI_OK iff successful. **/ int shishi_kdcreq_add_padata_tgs (Shishi * handle, Shishi_asn1 kdcreq, Shishi_asn1 apreq) { int res; char *data; size_t datalen; res = shishi_asn1_to_der (handle, apreq, &data, &datalen); if (res != SHISHI_OK) { shishi_error_printf (handle, "Could not DER encode AP-REQ: %s\n", shishi_strerror (res)); return res; } res = shishi_kdcreq_add_padata (handle, kdcreq, SHISHI_PA_TGS_REQ, data, datalen); free (data); if (res != SHISHI_OK) return res; return res; }