Path: blob/main/crypto/krb5/src/ccapi/common/cci_cred_union.c
39537 views
/* ccapi/common/cci_cred_union.c */1/*2* Copyright 2006 Massachusetts Institute of Technology.3* All Rights Reserved.4*5* Export of this software from the United States of America may6* require a specific license from the United States Government.7* It is the responsibility of any person or organization contemplating8* export to obtain such a license before exporting.9*10* WITHIN THAT CONSTRAINT, permission to use, copy, modify, and11* distribute this software and its documentation for any purpose and12* without fee is hereby granted, provided that the above copyright13* notice appear in all copies and that both that copyright notice and14* this permission notice appear in supporting documentation, and that15* the name of M.I.T. not be used in advertising or publicity pertaining16* to distribution of the software without specific, written prior17* permission. Furthermore if you modify this software you must label18* your software as modified software and not distribute it in such a19* fashion that it might be confused with the original M.I.T. software.20* M.I.T. makes no representations about the suitability of21* this software for any purpose. It is provided "as is" without express22* or implied warranty.23*/2425#include "cci_common.h"2627/* ------------------------------------------------------------------------ */2829static cc_uint32 cci_cc_data_contents_release (cc_data *io_ccdata)30{31cc_int32 err = ccNoError;3233if (!io_ccdata && io_ccdata->data) { err = ccErrBadParam; }3435if (!err) {36if (io_ccdata->length) {37memset (io_ccdata->data, 0, io_ccdata->length);38}39free (io_ccdata->data);40}4142return err;43}4445/* ------------------------------------------------------------------------ */4647static cc_uint32 cci_cc_data_release (cc_data *io_ccdata)48{49cc_int32 err = ccNoError;5051if (!io_ccdata) { err = ccErrBadParam; }5253if (!err) {54cci_cc_data_contents_release (io_ccdata);55free (io_ccdata);56}5758return err;59}6061/* ------------------------------------------------------------------------ */6263static cc_uint32 cci_cc_data_read (cc_data *io_ccdata,64k5_ipc_stream io_stream)65{66cc_int32 err = ccNoError;67cc_uint32 type = 0;68cc_uint32 length = 0;69char *data = NULL;7071if (!io_stream) { err = cci_check_error (ccErrBadParam); }72if (!io_ccdata) { err = cci_check_error (ccErrBadParam); }7374if (!err) {75err = krb5int_ipc_stream_read_uint32 (io_stream, &type);76}7778if (!err) {79err = krb5int_ipc_stream_read_uint32 (io_stream, &length);80}8182if (!err && length > 0) {83data = malloc (length);84if (!data) { err = cci_check_error (ccErrNoMem); }8586if (!err) {87err = krb5int_ipc_stream_read (io_stream, data, length);88}89}9091if (!err) {92io_ccdata->type = type;93io_ccdata->length = length;94io_ccdata->data = data;95data = NULL;96}9798free (data);99100return cci_check_error (err);101}102103/* ------------------------------------------------------------------------ */104105static cc_uint32 cci_cc_data_write (cc_data *in_ccdata,106k5_ipc_stream io_stream)107{108cc_int32 err = ccNoError;109110if (!io_stream) { err = cci_check_error (ccErrBadParam); }111if (!in_ccdata) { err = cci_check_error (ccErrBadParam); }112113if (!err) {114err = krb5int_ipc_stream_write_uint32 (io_stream, in_ccdata->type);115}116117if (!err) {118err = krb5int_ipc_stream_write_uint32 (io_stream, in_ccdata->length);119}120121if (!err && in_ccdata->length > 0) {122err = krb5int_ipc_stream_write (io_stream, in_ccdata->data, in_ccdata->length);123}124125return cci_check_error (err);126}127128#ifdef TARGET_OS_MAC129#pragma mark -130#endif131132/* ------------------------------------------------------------------------ */133134static cc_uint32 cci_cc_data_array_release (cc_data **io_ccdata_array)135{136cc_int32 err = ccNoError;137138if (!io_ccdata_array) { err = ccErrBadParam; }139140if (!err) {141cc_uint32 i;142143for (i = 0; io_ccdata_array && io_ccdata_array[i]; i++) {144cci_cc_data_release (io_ccdata_array[i]);145}146free (io_ccdata_array);147}148149return err;150}151152/* ------------------------------------------------------------------------ */153154static cc_uint32 cci_cc_data_array_read (cc_data ***io_ccdata_array,155k5_ipc_stream io_stream)156{157cc_int32 err = ccNoError;158cc_uint32 count = 0;159cc_data **array = NULL;160cc_uint32 i;161162if (!io_stream ) { err = cci_check_error (ccErrBadParam); }163if (!io_ccdata_array) { err = cci_check_error (ccErrBadParam); }164165if (!err) {166err = krb5int_ipc_stream_read_uint32 (io_stream, &count);167}168169if (!err && count > 0) {170array = malloc ((count + 1) * sizeof (*array));171if (array) {172for (i = 0; i <= count; i++) { array[i] = NULL; }173} else {174err = cci_check_error (ccErrNoMem);175}176}177178if (!err) {179for (i = 0; !err && i < count; i++) {180array[i] = malloc (sizeof (cc_data));181if (!array[i]) { err = cci_check_error (ccErrNoMem); }182183if (!err) {184err = cci_cc_data_read (array[i], io_stream);185}186}187}188189if (!err) {190*io_ccdata_array = array;191array = NULL;192}193194cci_cc_data_array_release (array);195196return cci_check_error (err);197}198199/* ------------------------------------------------------------------------ */200201static cc_uint32 cci_cc_data_array_write (cc_data **in_ccdata_array,202k5_ipc_stream io_stream)203{204cc_int32 err = ccNoError;205cc_uint32 count = 0;206207if (!io_stream) { err = cci_check_error (ccErrBadParam); }208/* in_ccdata_array may be NULL */209210if (!err) {211for (count = 0; in_ccdata_array && in_ccdata_array[count]; count++);212213err = krb5int_ipc_stream_write_uint32 (io_stream, count);214}215216if (!err) {217cc_uint32 i;218219for (i = 0; !err && i < count; i++) {220err = cci_cc_data_write (in_ccdata_array[i], io_stream);221}222}223224return cci_check_error (err);225}226227#ifdef TARGET_OS_MAC228#pragma mark -229#endif230231/* ------------------------------------------------------------------------ */232233cc_credentials_v5_t cci_credentials_v5_initializer = {234NULL,235NULL,236{ 0, 0, NULL },2370, 0, 0, 0, 0, 0,238NULL,239{ 0, 0, NULL },240{ 0, 0, NULL },241NULL242};243244/* ------------------------------------------------------------------------ */245246static cc_uint32 cci_credentials_v5_release (cc_credentials_v5_t *io_v5creds)247{248cc_int32 err = ccNoError;249250if (!io_v5creds) { err = ccErrBadParam; }251252if (!err) {253free (io_v5creds->client);254free (io_v5creds->server);255cci_cc_data_contents_release (&io_v5creds->keyblock);256cci_cc_data_array_release (io_v5creds->addresses);257cci_cc_data_contents_release (&io_v5creds->ticket);258cci_cc_data_contents_release (&io_v5creds->second_ticket);259cci_cc_data_array_release (io_v5creds->authdata);260free (io_v5creds);261}262263return err;264}265266/* ------------------------------------------------------------------------ */267268static cc_uint32 cci_credentials_v5_read (cc_credentials_v5_t **out_v5creds,269k5_ipc_stream io_stream)270{271cc_int32 err = ccNoError;272cc_credentials_v5_t *v5creds = NULL;273274if (!io_stream ) { err = cci_check_error (ccErrBadParam); }275if (!out_v5creds) { err = cci_check_error (ccErrBadParam); }276277if (!err) {278v5creds = malloc (sizeof (*v5creds));279if (v5creds) {280*v5creds = cci_credentials_v5_initializer;281} else {282err = cci_check_error (ccErrNoMem);283}284}285286if (!err) {287err = krb5int_ipc_stream_read_string (io_stream, &v5creds->client);288}289290if (!err) {291err = krb5int_ipc_stream_read_string (io_stream, &v5creds->server);292}293294if (!err) {295err = cci_cc_data_read (&v5creds->keyblock, io_stream);296}297298if (!err) {299err = krb5int_ipc_stream_read_time (io_stream, &v5creds->authtime);300}301302if (!err) {303err = krb5int_ipc_stream_read_time (io_stream, &v5creds->starttime);304}305306if (!err) {307err = krb5int_ipc_stream_read_time (io_stream, &v5creds->endtime);308}309310if (!err) {311err = krb5int_ipc_stream_read_time (io_stream, &v5creds->renew_till);312}313314if (!err) {315err = krb5int_ipc_stream_read_uint32 (io_stream, &v5creds->is_skey);316}317318if (!err) {319err = krb5int_ipc_stream_read_uint32 (io_stream, &v5creds->ticket_flags);320}321322if (!err) {323err = cci_cc_data_array_read (&v5creds->addresses, io_stream);324}325326if (!err) {327err = cci_cc_data_read (&v5creds->ticket, io_stream);328}329330if (!err) {331err = cci_cc_data_read (&v5creds->second_ticket, io_stream);332}333334if (!err) {335err = cci_cc_data_array_read (&v5creds->authdata, io_stream);336}337338if (!err) {339*out_v5creds = v5creds;340v5creds = NULL;341}342343cci_credentials_v5_release (v5creds);344345return cci_check_error (err);346}347348/* ------------------------------------------------------------------------ */349350static cc_uint32 cci_credentials_v5_write (cc_credentials_v5_t *in_v5creds,351k5_ipc_stream io_stream)352{353cc_int32 err = ccNoError;354355if (!io_stream ) { err = cci_check_error (ccErrBadParam); }356if (!in_v5creds) { err = cci_check_error (ccErrBadParam); }357358if (!err) {359err = krb5int_ipc_stream_write_string (io_stream, in_v5creds->client);360}361362if (!err) {363err = krb5int_ipc_stream_write_string (io_stream, in_v5creds->server);364}365366if (!err) {367err = cci_cc_data_write (&in_v5creds->keyblock, io_stream);368}369370if (!err) {371err = krb5int_ipc_stream_write_time (io_stream, in_v5creds->authtime);372}373374if (!err) {375err = krb5int_ipc_stream_write_time (io_stream, in_v5creds->starttime);376}377378if (!err) {379err = krb5int_ipc_stream_write_time (io_stream, in_v5creds->endtime);380}381382if (!err) {383err = krb5int_ipc_stream_write_time (io_stream, in_v5creds->renew_till);384}385386if (!err) {387err = krb5int_ipc_stream_write_uint32 (io_stream, in_v5creds->is_skey);388}389390if (!err) {391err = krb5int_ipc_stream_write_uint32 (io_stream, in_v5creds->ticket_flags);392}393394if (!err) {395err = cci_cc_data_array_write (in_v5creds->addresses, io_stream);396}397398if (!err) {399err = cci_cc_data_write (&in_v5creds->ticket, io_stream);400}401402if (!err) {403err = cci_cc_data_write (&in_v5creds->second_ticket, io_stream);404}405406if (!err) {407err = cci_cc_data_array_write (in_v5creds->authdata, io_stream);408}409410411return cci_check_error (err);412}413414#ifdef TARGET_OS_MAC415#pragma mark -416#endif417418/* ------------------------------------------------------------------------ */419420cc_uint32 cci_credentials_union_release (cc_credentials_union *io_cred_union)421{422cc_int32 err = ccNoError;423424if (!io_cred_union) { err = ccErrBadParam; }425426if (!err) {427if (io_cred_union->version == cc_credentials_v5) {428cci_credentials_v5_release (io_cred_union->credentials.credentials_v5);429}430free (io_cred_union);431}432433return err;434}435436/* ------------------------------------------------------------------------ */437438cc_uint32 cci_credentials_union_read (cc_credentials_union **out_credentials_union,439k5_ipc_stream io_stream)440{441cc_int32 err = ccNoError;442cc_credentials_union *credentials_union = NULL;443444if (!io_stream ) { err = cci_check_error (ccErrBadParam); }445if (!out_credentials_union) { err = cci_check_error (ccErrBadParam); }446447if (!err) {448credentials_union = calloc (1, sizeof (*credentials_union));449if (!credentials_union) { err = cci_check_error (ccErrNoMem); }450}451452if (!err) {453err = krb5int_ipc_stream_read_uint32 (io_stream, &credentials_union->version);454}455456if (!err) {457if (credentials_union->version == cc_credentials_v5) {458err = cci_credentials_v5_read (&credentials_union->credentials.credentials_v5,459io_stream);460461462} else {463err = ccErrBadCredentialsVersion;464}465}466467if (!err) {468*out_credentials_union = credentials_union;469credentials_union = NULL;470}471472if (credentials_union) { cci_credentials_union_release (credentials_union); }473474return cci_check_error (err);475}476477/* ------------------------------------------------------------------------ */478479cc_uint32 cci_credentials_union_write (const cc_credentials_union *in_credentials_union,480k5_ipc_stream io_stream)481{482cc_int32 err = ccNoError;483484if (!io_stream ) { err = cci_check_error (ccErrBadParam); }485if (!in_credentials_union) { err = cci_check_error (ccErrBadParam); }486487if (!err) {488err = krb5int_ipc_stream_write_uint32 (io_stream, in_credentials_union->version);489}490491if (!err) {492if (in_credentials_union->version == cc_credentials_v5) {493err = cci_credentials_v5_write (in_credentials_union->credentials.credentials_v5,494io_stream);495496} else {497err = ccErrBadCredentialsVersion;498}499}500501return cci_check_error (err);502}503504#ifdef TARGET_OS_MAC505#pragma mark -506#pragma mark -- CCAPI v2 Compat --507#endif508509/* ------------------------------------------------------------------------ */510511cc_credentials_v5_compat cci_credentials_v5_compat_initializer = {512NULL,513NULL,514{ 0, 0, NULL },5150, 0, 0, 0, 0, 0,516NULL,517{ 0, 0, NULL },518{ 0, 0, NULL },519NULL520};521522/* ------------------------------------------------------------------------ */523524cc_uint32 cci_cred_union_release (cred_union *io_cred_union)525{526cc_int32 err = ccNoError;527528if (!io_cred_union) { err = ccErrBadParam; }529530if (!err) {531if (io_cred_union->cred_type == CC_CRED_V5) {532free (io_cred_union->cred.pV5Cred->client);533free (io_cred_union->cred.pV5Cred->server);534cci_cc_data_contents_release (&io_cred_union->cred.pV5Cred->keyblock);535cci_cc_data_array_release (io_cred_union->cred.pV5Cred->addresses);536cci_cc_data_contents_release (&io_cred_union->cred.pV5Cred->ticket);537cci_cc_data_contents_release (&io_cred_union->cred.pV5Cred->second_ticket);538cci_cc_data_array_release (io_cred_union->cred.pV5Cred->authdata);539free (io_cred_union->cred.pV5Cred);540}541free (io_cred_union);542}543544return err;545}546547/* ------------------------------------------------------------------------ */548549static cc_uint32 cci_cc_data_copy_contents (cc_data *io_ccdata,550cc_data *in_ccdata)551{552cc_int32 err = ccNoError;553char *data = NULL;554555if (!io_ccdata) { err = cci_check_error (ccErrBadParam); }556if (!in_ccdata) { err = cci_check_error (ccErrBadParam); }557558if (!err && in_ccdata->length > 0) {559data = malloc (in_ccdata->length);560if (data) {561memcpy (data, in_ccdata->data, in_ccdata->length);562} else {563err = cci_check_error (ccErrNoMem);564}565}566567if (!err) {568io_ccdata->type = in_ccdata->type;569io_ccdata->length = in_ccdata->length;570io_ccdata->data = data;571data = NULL;572}573574free (data);575576return cci_check_error (err);577}578579/* ------------------------------------------------------------------------ */580581static cc_uint32 cci_cc_data_array_copy (cc_data ***io_ccdata_array,582cc_data **in_ccdata_array)583{584cc_int32 err = ccNoError;585cc_uint32 count = 0;586cc_data **array = NULL;587cc_uint32 i;588589if (!io_ccdata_array) { err = cci_check_error (ccErrBadParam); }590591if (!err) {592for (count = 0; in_ccdata_array && in_ccdata_array[count]; count++);593}594595if (!err && count > 0) {596array = malloc ((count + 1) * sizeof (*array));597if (array) {598for (i = 0; i <= count; i++) { array[i] = NULL; }599} else {600err = cci_check_error (ccErrNoMem);601}602}603604if (!err) {605for (i = 0; !err && i < count; i++) {606array[i] = malloc (sizeof (cc_data));607if (!array[i]) { err = cci_check_error (ccErrNoMem); }608609if (!err) {610err = cci_cc_data_copy_contents (array[i], in_ccdata_array[i]);611}612}613}614615if (!err) {616*io_ccdata_array = array;617array = NULL;618}619620cci_cc_data_array_release (array);621622return cci_check_error (err);623}624625/* ------------------------------------------------------------------------ */626627cc_uint32 cci_credentials_union_to_cred_union (const cc_credentials_union *in_credentials_union,628cred_union **out_cred_union)629{630cc_int32 err = ccNoError;631cred_union *compat_cred_union = NULL;632633if (!in_credentials_union) { err = cci_check_error (ccErrBadParam); }634if (!out_cred_union ) { err = cci_check_error (ccErrBadParam); }635636if (!err) {637compat_cred_union = calloc (1, sizeof (*compat_cred_union));638if (!compat_cred_union) { err = cci_check_error (ccErrNoMem); }639}640641if (!err) {642if (in_credentials_union->version == cc_credentials_v5) {643cc_credentials_v5_t *v5creds = in_credentials_union->credentials.credentials_v5;644cc_credentials_v5_compat *compat_v5creds = NULL;645646compat_v5creds = malloc (sizeof (*compat_v5creds));647if (compat_v5creds) {648*compat_v5creds = cci_credentials_v5_compat_initializer;649} else {650err = cci_check_error (ccErrNoMem);651}652653if (!err) {654if (!v5creds->client) {655err = cci_check_error (ccErrBadParam);656} else {657compat_v5creds->client = strdup (v5creds->client);658if (!compat_v5creds->client) { err = cci_check_error (ccErrNoMem); }659}660}661662if (!err) {663if (!v5creds->server) {664err = cci_check_error (ccErrBadParam);665} else {666compat_v5creds->server = strdup (v5creds->server);667if (!compat_v5creds->server) { err = cci_check_error (ccErrNoMem); }668}669}670671if (!err) {672err = cci_cc_data_copy_contents (&compat_v5creds->keyblock, &v5creds->keyblock);673}674675if (!err) {676err = cci_cc_data_array_copy (&compat_v5creds->addresses, v5creds->addresses);677}678679if (!err) {680err = cci_cc_data_copy_contents (&compat_v5creds->ticket, &v5creds->ticket);681}682683if (!err) {684err = cci_cc_data_copy_contents (&compat_v5creds->second_ticket, &v5creds->second_ticket);685}686687if (!err) {688err = cci_cc_data_array_copy (&compat_v5creds->authdata, v5creds->authdata);689}690691if (!err) {692compat_cred_union->cred_type = CC_CRED_V5;693compat_cred_union->cred.pV5Cred = compat_v5creds;694695compat_v5creds->keyblock = v5creds->keyblock;696compat_v5creds->authtime = v5creds->authtime;697compat_v5creds->starttime = v5creds->starttime;698compat_v5creds->endtime = v5creds->endtime;699compat_v5creds->renew_till = v5creds->renew_till;700compat_v5creds->is_skey = v5creds->is_skey;701compat_v5creds->ticket_flags = v5creds->ticket_flags;702}703} else {704err = cci_check_error (ccErrBadCredentialsVersion);705}706}707708if (!err) {709*out_cred_union = compat_cred_union;710compat_cred_union = NULL;711}712713if (compat_cred_union) { cci_cred_union_release (compat_cred_union); }714715return cci_check_error (err);716}717718/* ------------------------------------------------------------------------ */719720cc_uint32 cci_cred_union_to_credentials_union (const cred_union *in_cred_union,721cc_credentials_union **out_credentials_union)722{723cc_int32 err = ccNoError;724cc_credentials_union *creds_union = NULL;725726if (!in_cred_union ) { err = cci_check_error (ccErrBadParam); }727if (!out_credentials_union) { err = cci_check_error (ccErrBadParam); }728729if (!err) {730creds_union = calloc (1, sizeof (*creds_union));731if (!creds_union) { err = cci_check_error (ccErrNoMem); }732}733734if (!err) {735if (in_cred_union->cred_type == CC_CRED_V5) {736cc_credentials_v5_compat *compat_v5creds = in_cred_union->cred.pV5Cred;737cc_credentials_v5_t *v5creds = NULL;738739if (!err) {740v5creds = malloc (sizeof (*v5creds));741if (v5creds) {742*v5creds = cci_credentials_v5_initializer;743} else {744err = cci_check_error (ccErrNoMem);745}746}747748if (!err) {749if (!compat_v5creds->client) {750err = cci_check_error (ccErrBadParam);751} else {752v5creds->client = strdup (compat_v5creds->client);753if (!v5creds->client) { err = cci_check_error (ccErrNoMem); }754}755}756757if (!err) {758if (!compat_v5creds->server) {759err = cci_check_error (ccErrBadParam);760} else {761v5creds->server = strdup (compat_v5creds->server);762if (!v5creds->server) { err = cci_check_error (ccErrNoMem); }763}764}765766if (!err) {767err = cci_cc_data_copy_contents (&v5creds->keyblock, &compat_v5creds->keyblock);768}769770if (!err) {771err = cci_cc_data_array_copy (&v5creds->addresses, compat_v5creds->addresses);772}773774if (!err) {775err = cci_cc_data_copy_contents (&v5creds->ticket, &compat_v5creds->ticket);776}777778if (!err) {779err = cci_cc_data_copy_contents (&v5creds->second_ticket, &compat_v5creds->second_ticket);780}781782if (!err) {783err = cci_cc_data_array_copy (&v5creds->authdata, compat_v5creds->authdata);784}785786if (!err) {787creds_union->version = cc_credentials_v5;788creds_union->credentials.credentials_v5 = v5creds;789790v5creds->authtime = compat_v5creds->authtime;791v5creds->starttime = compat_v5creds->starttime;792v5creds->endtime = compat_v5creds->endtime;793v5creds->renew_till = compat_v5creds->renew_till;794v5creds->is_skey = compat_v5creds->is_skey;795v5creds->ticket_flags = compat_v5creds->ticket_flags;796}797798} else {799err = cci_check_error (ccErrBadCredentialsVersion);800}801}802803if (!err) {804*out_credentials_union = creds_union;805creds_union = NULL;806}807808if (creds_union) { cci_credentials_union_release (creds_union); }809810return cci_check_error (err);811}812813/* ------------------------------------------------------------------------ */814815cc_uint32 cci_cred_union_compare_to_credentials_union (const cred_union *in_cred_union_compat,816const cc_credentials_union *in_credentials_union,817cc_uint32 *out_equal)818{819cc_int32 err = ccNoError;820cc_uint32 equal = 0;821822if (!in_cred_union_compat) { err = cci_check_error (ccErrBadParam); }823if (!in_credentials_union) { err = cci_check_error (ccErrBadParam); }824if (!out_equal ) { err = cci_check_error (ccErrBadParam); }825826if (!err) {827if (in_cred_union_compat->cred_type == CC_CRED_V5 &&828in_credentials_union->version == cc_credentials_v5) {829cc_credentials_v5_compat *old_creds_v5 = in_cred_union_compat->cred.pV5Cred;830cc_credentials_v5_t *new_creds_v5 = in_credentials_union->credentials.credentials_v5;831832/* Really should use krb5_parse_name and krb5_principal_compare */833if (old_creds_v5 && new_creds_v5 &&834!strcmp (old_creds_v5->client, new_creds_v5->client) &&835!strcmp (old_creds_v5->server, new_creds_v5->server) &&836(old_creds_v5->starttime == new_creds_v5->starttime)) {837equal = 1;838}839}840}841842if (!err) {843*out_equal = equal;844}845846return cci_check_error (err);847}848849850