/** * shishi_tgs_sendrecv_hint: * @tgs: structure that holds information about TGS exchange * @hint: additional parameters that modify connection behaviour, or %NULL. * * Send TGS-REQ and receive TGS-REP or KRB-ERROR. This is the * subsequent authentication, usually used to acquire server tickets. * The @hint structure can be used to set, e.g., parameters for TLS * authentication. * * Return value: Returns SHISHI_OK iff successful. **/ int shishi_tgs_sendrecv_hint (Shishi_tgs * tgs, Shishi_tkts_hint * hint) { int res; if (VERBOSE (tgs->handle)) printf ("Sending TGS-REQ...\n"); if (VERBOSEASN1 (tgs->handle)) shishi_kdcreq_print (tgs->handle, stdout, tgs->tgsreq); res = shishi_kdcreq_sendrecv_hint (tgs->handle, tgs->tgsreq, &tgs->tgsrep, hint); if (res == SHISHI_GOT_KRBERROR) { tgs->krberror = tgs->tgsrep; tgs->tgsrep = NULL; if (VERBOSE (tgs->handle)) printf ("Received KRB-ERROR...\n"); if (VERBOSEASN1 (tgs->handle)) shishi_krberror_print (tgs->handle, stdout, tgs->krberror); } if (res != SHISHI_OK) return res; if (VERBOSE (tgs->handle)) printf ("Received TGS-REP...\n"); if (VERBOSEASN1 (tgs->handle)) shishi_kdcrep_print (tgs->handle, stdout, tgs->tgsrep); return SHISHI_OK; }
/** * shishi_kdcreq_get_padata_tgs: * @handle: shishi handle as allocated by shishi_init(). * @kdcreq: KDC-REQ to get PA-TGS-REQ from. * @apreq: Output variable with newly allocated AP-REQ. * * Extract TGS pre-authentication data from KDC-REQ. The data is an * AP-REQ that authenticates the request. This function call * shishi_kdcreq_get_padata() with a SHISHI_PA_TGS_REQ padatatype and * DER decode the result (if any). * * Return value: Returns SHISHI_OK iff successful. **/ int shishi_kdcreq_get_padata_tgs (Shishi * handle, Shishi_asn1 kdcreq, Shishi_asn1 * apreq) { char *der; size_t derlen; int rc; if (VERBOSE (handle)) printf ("Extracting AP-REQ from KDC-REQ...\n"); rc = shishi_kdcreq_get_padata (handle, kdcreq, SHISHI_PA_TGS_REQ, &der, &derlen); if (rc != SHISHI_OK) return rc; *apreq = shishi_der2asn1_apreq (handle, der, derlen); if (!*apreq) return SHISHI_ASN1_ERROR; if (VERBOSEASN1 (handle)) shishi_apreq_print (handle, stdout, *apreq); 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; }
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; }