/** * shishi_encapreppart_time_copy: * @handle: shishi handle as allocated by shishi_init(). * @encapreppart: EncAPRepPart as allocated by shishi_encapreppart(). * @authenticator: Authenticator to copy time fields from. * * Copy time fields from Authenticator into EncAPRepPart. * * Return value: Returns SHISHI_OK iff successful. **/ int shishi_encapreppart_time_copy (Shishi * handle, Shishi_asn1 encapreppart, Shishi_asn1 authenticator) { char *buf; size_t buflen; int res; res = shishi_asn1_read (handle, authenticator, "cusec", &buf, &buflen); if (res != SHISHI_OK) return res; res = shishi_asn1_write (handle, encapreppart, "cusec", buf, buflen); free (buf); if (res != SHISHI_OK) return res; res = shishi_asn1_read (handle, authenticator, "ctime", &buf, &buflen); if (res != SHISHI_OK) return res; res = shishi_asn1_write (handle, encapreppart, "ctime", buf, buflen); free (buf); if (res != SHISHI_OK) return res; return SHISHI_OK; }
/** * shishi_authenticator_get_subkey: * @handle: shishi handle as allocated by shishi_init(). * @authenticator: authenticator as allocated by shishi_authenticator(). * @subkey: output newly allocated subkey from authenticator. * * Read subkey value from authenticator. * * Return value: Returns SHISHI_OK if successful or SHISHI_ASN1_NO_ELEMENT * if subkey is not present. **/ int shishi_authenticator_get_subkey (Shishi * handle, Shishi_asn1 authenticator, Shishi_key ** subkey) { int res; int subkeytype; char *subkeyvalue; size_t subkeylen; res = shishi_asn1_read_int32 (handle, authenticator, "subkey.keytype", &subkeytype); if (res != SHISHI_OK) return res; res = shishi_asn1_read (handle, authenticator, "subkey.keyvalue", &subkeyvalue, &subkeylen); if (res != SHISHI_OK) return res; res = shishi_key (handle, subkey); if (res != SHISHI_OK) return res; shishi_key_type_set (*subkey, subkeytype); shishi_key_value_set (*subkey, subkeyvalue); return SHISHI_OK; }
/** * shishi_encapreppart_get_key: * @handle: shishi handle as allocated by shishi_init(). * @encapreppart: input EncAPRepPart variable. * @key: newly allocated key. * * Extract the subkey from the encrypted AP-REP part. * * Return value: Returns SHISHI_OK iff succesful. **/ int shishi_encapreppart_get_key (Shishi * handle, Shishi_asn1 encapreppart, Shishi_key ** key) { int res; char *buf; size_t buflen; int32_t keytype; res = shishi_asn1_read_int32 (handle, encapreppart, "subkey.keytype", &keytype); if (res != SHISHI_OK) return res; res = shishi_asn1_read (handle, encapreppart, "subkey.keyvalue", &buf, &buflen); if (res != SHISHI_OK) return res; if (shishi_cipher_keylen (keytype) != buflen) return SHISHI_ENCAPREPPART_BAD_KEYTYPE; res = shishi_key_from_value (handle, keytype, buf, key); free (buf); if (res != SHISHI_OK) return res; return SHISHI_OK; }
/** * shishi_encticketpart_get_key: * @handle: shishi handle as allocated by shishi_init(). * @encticketpart: input EncTicketPart variable. * @key: newly allocated key. * * Extract the session key in the Ticket. * * Return value: Returns %SHISHI_OK iff successful. **/ int shishi_encticketpart_get_key (Shishi * handle, Shishi_asn1 encticketpart, Shishi_key ** key) { int res; char *buf; size_t buflen; int32_t keytype; res = shishi_asn1_read_int32 (handle, encticketpart, "key.keytype", &keytype); if (res != SHISHI_OK) return res; res = shishi_asn1_read (handle, encticketpart, "key.keyvalue", &buf, &buflen); if (res != SHISHI_OK) return res; res = shishi_key_from_value (handle, keytype, buf, key); free (buf); if (res != SHISHI_OK) return res; return SHISHI_OK; }
/** * shishi_authenticator_authorizationdata: * @handle: shishi handle as allocated by shishi_init(). * @authenticator: authenticator as allocated by shishi_authenticator(). * @adtype: output authorization data type. * @addata: newly allocated output authorization data. * @addatalen: on output, actual size of newly allocated authorization data. * @nth: element number of authorization-data to extract. * * Extract n:th authorization data from authenticator. The first * field is 1. * * Return value: Returns SHISHI_OK iff successful. **/ int shishi_authenticator_authorizationdata (Shishi * handle, Shishi_asn1 authenticator, int32_t * adtype, char **addata, size_t * addatalen, size_t nth) { char *format; int res; size_t i; res = shishi_asn1_number_of_elements (handle, authenticator, "authorization-data", &i); if (res != SHISHI_OK) return SHISHI_ASN1_ERROR; if (nth > i) return SHISHI_OUT_OF_RANGE; asprintf (&format, "authorization-data.?%zu.ad-type", nth); res = shishi_asn1_read_int32 (handle, authenticator, format, adtype); free (format); if (res != SHISHI_OK) return res; asprintf (&format, "authorization-data.?%zu.ad-data", i); res = shishi_asn1_read (handle, authenticator, format, addata, addatalen); free (format); if (res != SHISHI_OK) return res; return SHISHI_OK; }
int shishi_encticketpart_crealm (Shishi * handle, Shishi_asn1 encticketpart, char **crealm, size_t * crealmlen) { return shishi_asn1_read (handle, encticketpart, "crealm", crealm, crealmlen); }
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_authenticator_cksum: * @handle: shishi handle as allocated by shishi_init(). * @authenticator: authenticator as allocated by shishi_authenticator(). * @cksumtype: output checksum type. * @cksum: newly allocated output checksum data from authenticator. * @cksumlen: on output, actual size of allocated output checksum data buffer. * * Read checksum value from authenticator. @cksum is allocated by * this function, and it is the responsibility of caller to deallocate * it. * * Return value: Returns SHISHI_OK iff successful. **/ int shishi_authenticator_cksum (Shishi * handle, Shishi_asn1 authenticator, int32_t * cksumtype, char **cksum, size_t * cksumlen) { int res; res = shishi_asn1_read_int32 (handle, authenticator, "cksum.cksumtype", cksumtype); if (res != SHISHI_OK) return res; res = shishi_asn1_read (handle, authenticator, "cksum.checksum", cksum, cksumlen); if (res != SHISHI_OK) return res; return SHISHI_OK; }
/** * shishi_kdcreq_get_padata: * @handle: shishi handle as allocated by shishi_init(). * @kdcreq: KDC-REQ to get PA-DATA from. * @padatatype: type of PA-DATA, see Shishi_padata_type. * @out: output array with newly allocated PA-DATA value. * @outlen: size of output array with PA-DATA value. * * Get pre authentication data (PA-DATA) from KDC-REQ. Pre * authentication data is used to pass various information to KDC, * such as in case of a SHISHI_PA_TGS_REQ padatatype the AP-REQ that * authenticates the user to get the ticket. * * Return value: Returns SHISHI_OK iff successful. **/ int shishi_kdcreq_get_padata (Shishi * handle, Shishi_asn1 kdcreq, Shishi_padata_type padatatype, char **out, size_t * outlen) { char *format; int res; size_t i, n; res = shishi_asn1_number_of_elements (handle, kdcreq, "padata", &n); if (res != SHISHI_OK) return res; *out = NULL; *outlen = 0; for (i = 1; i <= n; i++) { int32_t patype; asprintf (&format, "padata.?%zu.padata-type", i); res = shishi_asn1_read_int32 (handle, kdcreq, format, &patype); free (format); if (res != SHISHI_OK) return res; if (patype == (int32_t) padatatype) { asprintf (&format, "padata.?%zu.padata-value", i); res = shishi_asn1_read (handle, kdcreq, format, out, outlen); free (format); if (res != SHISHI_OK) return res; break; } } return SHISHI_OK; }
/** * shishi_kdcreq_till: * @handle: Shishi library handle created by shishi_init(). * @kdcreq: KDC-REQ variable to get endtime from. * @till: pointer to newly allocated null terminated string containing * "till" field with generalized time. May be passed as %NULL * to only populate @tilllen. * @tilllen: pointer to length of @till for output, excluding the * terminating null. Set to %NULL, only @till is populated. * * Get "till" field, i.e., "endtime", in KDC-REQ as a null-terminated * string. The string is typically 15 characters long and is * allocated by this function. It is the responsibility of the * caller to deallocate it. Note that the output length @tilllen * does not include the terminating zero. * * Return value: Returns SHISHI_OK iff successful. **/ int shishi_kdcreq_till (Shishi * handle, Shishi_asn1 kdcreq, char **till, size_t * tilllen) { return shishi_asn1_read (handle, kdcreq, "req-body.till", till, tilllen); }
/** * shishi_apreq_get_ticket: * @handle: shishi handle as allocated by shishi_init(). * @apreq: AP-REQ variable to get ticket from. * @ticket: output variable to hold extracted ticket. * * Extract ticket from AP-REQ. * * Return value: Returns SHISHI_OK iff successful. **/ int shishi_apreq_get_ticket (Shishi * handle, Shishi_asn1 apreq, Shishi_asn1 * ticket) { char *buf; char *format; size_t buflen, i, n; int res; /* there's GOT to be an easier way to do this */ *ticket = shishi_ticket (handle); if (!*ticket) return SHISHI_ASN1_ERROR; res = shishi_asn1_read (handle, apreq, "ticket.tkt-vno", &buf, &buflen); if (res != SHISHI_OK) goto error; res = shishi_asn1_write (handle, *ticket, "tkt-vno", buf, buflen); free (buf); if (res != SHISHI_OK) goto error; res = shishi_asn1_read (handle, apreq, "ticket.realm", &buf, &buflen); if (res != SHISHI_OK) goto error; res = shishi_asn1_write (handle, *ticket, "realm", buf, buflen); free (buf); if (res != SHISHI_OK) goto error; res = shishi_asn1_read (handle, apreq, "ticket.sname.name-type", &buf, &buflen); if (res != SHISHI_OK) goto error; res = shishi_asn1_write (handle, *ticket, "sname.name-type", buf, buflen); free (buf); if (res != SHISHI_OK) goto error; res = shishi_asn1_number_of_elements (handle, apreq, "ticket.sname.name-string", &n); if (res != SHISHI_OK) goto error; for (i = 1; i <= n; i++) { res = shishi_asn1_write (handle, *ticket, "sname.name-string", "NEW", 1); if (res != SHISHI_OK) goto error; asprintf (&format, "ticket.sname.name-string.?%d", i); res = shishi_asn1_read (handle, apreq, format, &buf, &buflen); free (format); if (res != SHISHI_OK) goto error; asprintf (&format, "sname.name-string.?%d", i); res = shishi_asn1_write (handle, *ticket, format, buf, buflen); free (format); free (buf); if (res != SHISHI_OK) goto error; } res = shishi_asn1_read (handle, apreq, "ticket.enc-part.etype", &buf, &buflen); if (res != SHISHI_OK) goto error; res = shishi_asn1_write (handle, *ticket, "enc-part.etype", buf, buflen); free (buf); if (res != SHISHI_OK) goto error; res = shishi_asn1_read (handle, apreq, "ticket.enc-part.kvno", &buf, &buflen); if (res != SHISHI_OK && res != SHISHI_ASN1_NO_ELEMENT) goto error; if (res == SHISHI_ASN1_NO_ELEMENT) res = shishi_asn1_write (handle, *ticket, "enc-part.kvno", NULL, 0); else { res = shishi_asn1_write (handle, *ticket, "enc-part.kvno", buf, buflen); free (buf); } if (res != SHISHI_OK) goto error; res = shishi_asn1_read (handle, apreq, "ticket.enc-part.cipher", &buf, &buflen); if (res != SHISHI_OK) goto error; res = shishi_asn1_write (handle, *ticket, "enc-part.cipher", buf, buflen); free (buf); if (res != SHISHI_OK) goto error; return SHISHI_OK; error: shishi_asn1_done (handle, *ticket); return res; }
/** * shishi_apreq_set_ticket: * @handle: shishi handle as allocated by shishi_init(). * @apreq: AP-REQ to add ticket field to. * @ticket: input ticket to copy into AP-REQ ticket field. * * Copy ticket into AP-REQ. * * Return value: Returns SHISHI_OK iff successful. **/ int shishi_apreq_set_ticket (Shishi * handle, Shishi_asn1 apreq, Shishi_asn1 ticket) { int res; char *format; char *buf; size_t buflen, i, n; res = shishi_asn1_read (handle, ticket, "tkt-vno", &buf, &buflen); if (res != SHISHI_OK) return res; res = shishi_asn1_write (handle, apreq, "ticket.tkt-vno", buf, buflen); free (buf); if (res != SHISHI_OK) return res; res = shishi_asn1_read (handle, ticket, "realm", &buf, &buflen); if (res != SHISHI_OK) return res; res = shishi_asn1_write (handle, apreq, "ticket.realm", buf, buflen); free (buf); if (res != SHISHI_OK) return res; res = shishi_asn1_read (handle, ticket, "sname.name-type", &buf, &buflen); if (res != SHISHI_OK) return res; res = shishi_asn1_write (handle, apreq, "ticket.sname.name-type", buf, buflen); free (buf); if (res != SHISHI_OK) return res; res = shishi_asn1_number_of_elements (handle, ticket, "sname.name-string", &n); if (res != SHISHI_OK) return res; for (i = 1; i <= n; i++) { res = shishi_asn1_write (handle, apreq, "ticket.sname.name-string", "NEW", 1); if (res != SHISHI_OK) return res; asprintf (&format, "sname.name-string.?%d", i); res = shishi_asn1_read (handle, ticket, format, &buf, &buflen); free (format); if (res != SHISHI_OK) return res; asprintf (&format, "ticket.sname.name-string.?%d", i); res = shishi_asn1_write (handle, apreq, format, buf, buflen); free (format); free (buf); if (res != SHISHI_OK) return res; } res = shishi_asn1_read (handle, ticket, "enc-part.etype", &buf, &buflen); if (res != SHISHI_OK) return res; res = shishi_asn1_write (handle, apreq, "ticket.enc-part.etype", buf, buflen); free (buf); if (res != SHISHI_OK) return res; res = shishi_asn1_read (handle, ticket, "enc-part.kvno", &buf, &buflen); if (res != SHISHI_OK && res != SHISHI_ASN1_NO_ELEMENT) return res; if (res == SHISHI_ASN1_NO_ELEMENT) res = shishi_asn1_write (handle, apreq, "ticket.enc-part.kvno", NULL, 0); else { res = shishi_asn1_write (handle, apreq, "ticket.enc-part.kvno", buf, buflen); free (buf); } if (res != SHISHI_OK) return res; res = shishi_asn1_read (handle, ticket, "enc-part.cipher", &buf, &buflen); if (res != SHISHI_OK) return res; res = shishi_asn1_write (handle, apreq, "ticket.enc-part.cipher", buf, buflen); free (buf); if (res != SHISHI_OK) return res; return SHISHI_OK; }