diff options
author | Simo Sorce <ssorce@redhat.com> | 2012-07-06 11:15:15 -0400 |
---|---|---|
committer | Simo Sorce <ssorce@redhat.com> | 2012-07-30 10:31:47 -0400 |
commit | 505bc85ec31ad8cfa66be0dc99d19599cd1a9497 (patch) | |
tree | 9a3fef5fbf3af690b156b5d8cca82489bfc0c993 /util | |
parent | 03837bfd6dbf7fd1eaa437da22807d7061b99af7 (diff) | |
download | freeipa-505bc85ec31ad8cfa66be0dc99d19599cd1a9497.tar.gz freeipa-505bc85ec31ad8cfa66be0dc99d19599cd1a9497.tar.xz freeipa-505bc85ec31ad8cfa66be0dc99d19599cd1a9497.zip |
Move code into common krb5 utils
This moves the decoding function that reads the keys from the ber format
into a structure in the common krb5 util code right below the function
that encodes the same data structure into a ber format.
This way the 2 functions are in the same place and can be both used by
all ia components.
Diffstat (limited to 'util')
-rw-r--r-- | util/ipa_krb5.c | 150 | ||||
-rw-r--r-- | util/ipa_krb5.h | 2 |
2 files changed, 152 insertions, 0 deletions
diff --git a/util/ipa_krb5.c b/util/ipa_krb5.c index 0240c079e..934fd27d8 100644 --- a/util/ipa_krb5.c +++ b/util/ipa_krb5.c @@ -427,6 +427,156 @@ done: return ret; } +int ber_decode_krb5_key_data(struct berval *encoded, int *m_kvno, + int *numk, krb5_key_data **data) +{ + krb5_key_data *keys = NULL; + BerElement *be = NULL; + void *tmp; + int i = 0; + ber_tag_t tag; + ber_int_t major_vno; + ber_int_t minor_vno; + ber_int_t kvno; + ber_int_t mkvno; + ber_int_t type; + ber_tag_t seqtag; + ber_len_t seqlen; + ber_len_t setlen; + ber_tag_t retag; + ber_tag_t opttag; + struct berval tval; + int ret; + + be = ber_alloc_t(LBER_USE_DER); + if (!be) { + return ENOMEM; + } + + /* reinit the ber element with the new val */ + ber_init2(be, encoded, LBER_USE_DER); + + /* fill key_data struct with the data */ + retag = ber_scanf(be, "{t[i]t[i]t[i]t[i]t[{", + &tag, &major_vno, + &tag, &minor_vno, + &tag, &kvno, + &tag, &mkvno, + &seqtag); + if (retag == LBER_ERROR || + major_vno != 1 || + minor_vno != 1 || + seqtag != (LBER_CONSTRUCTED | LBER_CLASS_CONTEXT | 4)) { + ret = EINVAL; + goto done; + } + + retag = ber_skip_tag(be, &seqlen); + + /* sequence of keys */ + for (i = 0; retag == LBER_SEQUENCE; i++) { + + tmp = realloc(keys, (i + 1) * sizeof(krb5_key_data)); + if (!tmp) { + ret = ENOMEM; + goto done; + } + keys = tmp; + + memset(&keys[i], 0, sizeof(krb5_key_data)); + + keys[i].key_data_kvno = kvno; + + /* do we have a salt type ? (optional) */ + retag = ber_scanf(be, "t", &opttag); + if (retag == LBER_ERROR) { + ret = EINVAL; + goto done; + } + if (opttag == (LBER_CONSTRUCTED | LBER_CLASS_CONTEXT | 0)) { + keys[i].key_data_ver = 2; + + retag = ber_scanf(be, "[l{tl[i]", + &seqlen, &tag, &setlen, &type); + if (tag != (LBER_CONSTRUCTED | LBER_CLASS_CONTEXT | 0)) { + ret = EINVAL; + goto done; + } + keys[i].key_data_type[1] = type; + + /* do we have salt data ? (optional) */ + if (seqlen > setlen + 2) { + retag = ber_scanf(be, "t[o]", &tag, &tval); + if (retag == LBER_ERROR || + tag != (LBER_CONSTRUCTED | LBER_CLASS_CONTEXT | 1)) { + ret = EINVAL; + goto done; + } + keys[i].key_data_length[1] = tval.bv_len; + keys[i].key_data_contents[1] = (krb5_octet *)tval.bv_val; + } + + retag = ber_scanf(be, "}]t", &opttag); + if (retag == LBER_ERROR) { + ret = EINVAL; + goto done; + } + + } else { + keys[i].key_data_ver = 1; + } + + if (opttag != (LBER_CONSTRUCTED | LBER_CLASS_CONTEXT | 1)) { + ret = EINVAL; + goto done; + } + + /* get the key */ + retag = ber_scanf(be, "[{t[i]t[o]}]", &tag, &type, &tag, &tval); + if (retag == LBER_ERROR) { + ret = EINVAL; + goto done; + } + keys[i].key_data_type[0] = type; + keys[i].key_data_length[0] = tval.bv_len; + keys[i].key_data_contents[0] = (krb5_octet *)tval.bv_val; + + /* check for sk2params */ + retag = ber_peek_tag(be, &setlen); + if (retag == (LBER_CONSTRUCTED | LBER_CLASS_CONTEXT | 2)) { + /* not supported yet, skip */ + retag = ber_scanf(be, "t[x]}"); + } else { + retag = ber_scanf(be, "}"); + } + if (retag == LBER_ERROR) { + ret = EINVAL; + goto done; + } + + retag = ber_skip_tag(be, &seqlen); + } + + ret = 0; + +done: + ber_free(be, 0); /* internal buffer is 'encoded' */ + if (ret) { + for (i -= 1; keys && i >= 0; i--) { + free(keys[i].key_data_contents[0]); + free(keys[i].key_data_contents[1]); + } + free(keys); + keys = NULL; + mkvno = 0; + } + *m_kvno = mkvno; + *numk = i; + *data = keys; + return ret; +} + + krb5_error_code parse_bval_key_salt_tuples(krb5_context kcontext, const char * const *vals, int n_vals, diff --git a/util/ipa_krb5.h b/util/ipa_krb5.h index 97ffc47b5..7fb035572 100644 --- a/util/ipa_krb5.h +++ b/util/ipa_krb5.h @@ -49,6 +49,8 @@ void ipa_krb5_free_key_data(krb5_key_data *keys, int num_keys); int ber_encode_krb5_key_data(krb5_key_data *data, int numk, int mkvno, struct berval **encoded); +int ber_decode_krb5_key_data(struct berval *encoded, int *m_kvno, + int *numk, krb5_key_data **data); krb5_error_code parse_bval_key_salt_tuples(krb5_context kcontext, const char * const *vals, |