1 /* -*- mode: c; c-basic-offset: 4; indent-tabs-mode: nil -*- */
2 /* ... copyright ... */
5 * Novell key-format scheme:
7 * KrbKeySet ::= SEQUENCE {
8 * attribute-major-vno [0] UInt16,
9 * attribute-minor-vno [1] UInt16,
11 * mkvno [3] UInt32 OPTIONAL,
12 * keys [4] SEQUENCE OF KrbKey,
16 * KrbKey ::= SEQUENCE {
17 * salt [0] KrbSalt OPTIONAL,
18 * key [1] EncryptionKey,
19 * s2kparams [2] OCTET STRING OPTIONAL,
23 * KrbSalt ::= SEQUENCE {
25 * salt [1] OCTET STRING OPTIONAL
28 * EncryptionKey ::= SEQUENCE {
30 * keyvalue [1] OCTET STRING
39 #include "asn1_encode.h"
40 #include "asn1_decode.h"
41 #include "asn1_make.h"
46 /************************************************************************/
47 /* Encode the Principal's keys */
48 /************************************************************************/
51 * Imports from asn1_k_encode.c.
52 * XXX Must be manually synchronized for now.
54 IMPORT_TYPE(octetstring, unsigned char *);
55 IMPORT_TYPE(int32, krb5_int32);
57 DEFINTTYPE(int16, krb5_int16);
58 DEFINTTYPE(ui_2, krb5_ui_2);
60 static const struct field_info krbsalt_fields[] = {
61 FIELDOF_NORM(krb5_key_data, int16, key_data_type[1], 0, 0),
62 FIELDOF_OPTSTRINGL(krb5_key_data, octetstring, key_data_contents[1],
63 ui_2, key_data_length[1], 1, 0, 1),
66 optional_krbsalt (const void *p)
68 const krb5_key_data *k = p;
69 unsigned int optional = 0;
71 if (k->key_data_length[1] > 0)
72 optional |= (1u << 1);
76 DEFSEQTYPE(krbsalt, krb5_key_data, krbsalt_fields, optional_krbsalt);
77 static const struct field_info encryptionkey_fields[] = {
78 FIELDOF_NORM(krb5_key_data, int16, key_data_type[0], 0, 0),
79 FIELDOF_STRINGL(krb5_key_data, octetstring, key_data_contents[0],
80 ui_2, key_data_length[0], 1, 0),
82 DEFSEQTYPE(encryptionkey, krb5_key_data, encryptionkey_fields, 0);
84 static const struct field_info key_data_fields[] = {
85 FIELDOF_ENCODEAS(krb5_key_data, krbsalt, 0, 0),
86 FIELDOF_ENCODEAS(krb5_key_data, encryptionkey, 1, 0),
87 #if 0 /* We don't support this field currently. */
88 FIELDOF_blah(krb5_key_data, s2kparams, ...),
91 DEFSEQTYPE(key_data, krb5_key_data, key_data_fields, 0);
92 DEFPTRTYPE(ptr_key_data, key_data);
94 DEFFIELDTYPE(key_data_kvno, krb5_key_data,
95 FIELDOF_NORM(krb5_key_data, int16, key_data_kvno, -1, 0));
96 DEFPTRTYPE(ptr_key_data_kvno, key_data_kvno);
98 static const struct field_info ldap_key_seq_fields[] = {
99 FIELD_INT_IMM(1, 0, 0),
100 FIELD_INT_IMM(1, 1, 0),
101 FIELDOF_NORM(ldap_seqof_key_data, ptr_key_data_kvno, key_data, 2, 0),
102 FIELDOF_NORM(ldap_seqof_key_data, int32, mkvno, 3, 0), /* mkvno */
103 FIELDOF_SEQOF_LEN(ldap_seqof_key_data, ptr_key_data, key_data, n_key_data,
106 DEFSEQTYPE(ldap_key_seq, ldap_seqof_key_data, ldap_key_seq_fields, 0);
108 /* Export a function to do the whole encoding. */
109 MAKE_FULL_ENCODER(krb5int_ldap_encode_sequence_of_keys, ldap_key_seq);
111 /************************************************************************/
112 /* Decode the Principal's keys */
113 /************************************************************************/
115 #define cleanup(err) \
125 #define safe_syncbuf(outer,inner,buflen) \
126 if (! ((inner)->next == (inner)->bound + 1 && \
127 (inner)->next == (outer)->next + buflen)) \
128 cleanup (ASN1_BAD_LENGTH); \
129 asn1buf_sync((outer), (inner), 0, 0, 0, 0, 0);
131 static asn1_error_code
132 decode_tagged_integer (asn1buf *buf, asn1_tagnum expectedtag, long *val)
135 asn1_error_code ret = 0;
139 /* Work on a copy of 'buf' */
140 ret = asn1buf_imbed(&tmp, buf, 0, 1); checkerr;
141 ret = asn1_get_tag_2(&tmp, &t); checkerr;
142 if (t.tagnum != expectedtag)
143 cleanup (ASN1_MISSING_FIELD);
146 ret = asn1buf_imbed(&subbuf, &tmp, t.length, 0); checkerr;
147 ret = asn1_decode_integer(&subbuf, val); checkerr;
149 safe_syncbuf(&tmp, &subbuf, buflen);
156 #if 0 /* not currently used */
157 static asn1_error_code
158 decode_tagged_unsigned_integer (asn1buf *buf, int expectedtag, unsigned long *val)
161 asn1_error_code ret = 0;
165 /* Work on a copy of 'buf' */
166 ret = asn1buf_imbed(&tmp, buf, 0, 1); checkerr;
167 ret = asn1_get_tag_2(&tmp, &t); checkerr;
168 if (t.tagnum != expectedtag)
169 cleanup (ASN1_MISSING_FIELD);
172 ret = asn1buf_imbed(&subbuf, &tmp, t.length, 0); checkerr;
173 ret = asn1_decode_unsigned_integer(&subbuf, val); checkerr;
175 safe_syncbuf(&tmp, &subbuf, buflen);
183 static asn1_error_code
184 decode_tagged_octetstring (asn1buf *buf, asn1_tagnum expectedtag,
189 asn1_error_code ret = 0;
195 /* Work on a copy of 'buf' */
196 ret = asn1buf_imbed(&tmp, buf, 0, 1); checkerr;
197 ret = asn1_get_tag_2(&tmp, &t); checkerr;
198 if (t.tagnum != expectedtag)
199 cleanup (ASN1_MISSING_FIELD);
202 ret = asn1buf_imbed(&subbuf, &tmp, t.length, 0); checkerr;
203 ret = asn1_decode_octetstring (&subbuf, len, val); checkerr;
205 safe_syncbuf(&tmp, &subbuf, buflen);
214 static asn1_error_code
215 asn1_decode_key(asn1buf *buf, krb5_key_data *key)
217 int full_buflen, seqindef;
223 key->key_data_contents[0] = NULL;
224 key->key_data_contents[1] = NULL;
226 ret = asn1_get_sequence(buf, &length, &seqindef); checkerr;
227 full_buflen = length;
228 ret = asn1buf_imbed(&subbuf, buf, length, seqindef); checkerr;
230 asn1_get_tag_2(&subbuf, &t);
238 key->key_data_ver = 2;
239 asn1_get_sequence(&subbuf, &length, &seqindef);
240 salt_buflen = length;
241 asn1buf_imbed(&slt, &subbuf, length, seqindef);
243 ret = decode_tagged_integer (&slt, 0, &keytype);
244 key->key_data_type[1] = keytype; /* XXX range check?? */
247 if (asn1buf_remains(&slt, 0) != 0) { /* Salt value is optional */
248 ret = decode_tagged_octetstring (&slt, 1, &keylen,
249 &key->key_data_contents[1]);
253 safe_syncbuf (&subbuf, &slt, salt_buflen);
254 key->key_data_length[1] = keylen; /* XXX range check?? */
256 ret = asn1_get_tag_2(&subbuf, &t); checkerr;
258 key->key_data_ver = 1;
268 cleanup (ASN1_MISSING_FIELD);
270 ret = asn1_get_sequence(&subbuf, &length, &seqindef); checkerr;
272 ret = asn1buf_imbed(&kbuf, &subbuf, length, seqindef); checkerr;
274 ret = decode_tagged_integer (&kbuf, 0, &lval);
276 key->key_data_type[0] = lval; /* XXX range check? */
278 ret = decode_tagged_octetstring (&kbuf, 1, &ival,
279 &key->key_data_contents[0]); checkerr;
280 key->key_data_length[0] = ival; /* XXX range check? */
282 safe_syncbuf (&subbuf, &kbuf, key_buflen);
285 safe_syncbuf (buf, &subbuf, full_buflen);
289 free (key->key_data_contents[0]);
290 key->key_data_contents[0] = NULL;
291 free (key->key_data_contents[1]);
292 key->key_data_contents[1] = NULL;
298 krb5int_ldap_decode_sequence_of_keys (krb5_data *in, ldap_seqof_key_data **rep)
300 ldap_seqof_key_data *repval;
302 krb5_int16 *n_key_data;
313 repval = calloc(1,sizeof(ldap_seqof_key_data));
315 out = &repval->key_data;
316 n_key_data = &repval->n_key_data;
317 mkvno = &repval->mkvno;
322 ret = asn1buf_wrap_data(&buf, in); checkerr;
324 ret = asn1_get_sequence(&buf, &length, &seqindef); checkerr;
325 ret = asn1buf_imbed(&subbuf, &buf, length, seqindef); checkerr;
327 /* attribute-major-vno */
328 ret = decode_tagged_integer (&subbuf, 0, &lval); checkerr;
329 maj = lval; /* XXX range check? */
331 /* attribute-minor-vno */
332 ret = decode_tagged_integer (&subbuf, 1, &lval); checkerr;
333 min = lval; /* XXX range check? */
335 if (maj != 1 || min != 1)
336 cleanup (ASN1_BAD_FORMAT);
338 /* kvno (assuming all keys in array have same version) */
339 ret = decode_tagged_integer (&subbuf, 2, &lval); checkerr;
340 kvno = lval; /* XXX range check? */
342 /* mkvno (optional) */
343 ret = decode_tagged_integer (&subbuf, 3, &lval); checkerr;
344 *mkvno = lval; /* XXX range check? */
346 ret = asn1_get_tag_2(&subbuf, &t); checkerr;
348 /* Sequence of keys */
353 cleanup (ASN1_MISSING_FIELD);
354 ret = asn1_get_sequence(&subbuf, &length, &seqindef); checkerr;
356 ret = asn1buf_imbed(&keyseq, &subbuf, length, seqindef); checkerr;
357 for (i = 1, *out = NULL; ; i++) {
359 tmp = (krb5_key_data *) realloc (*out, i * sizeof (krb5_key_data));
363 (*out)[i - 1].key_data_kvno = kvno;
364 ret = asn1_decode_key(&keyseq, &(*out)[i - 1]); checkerr;
366 if (asn1buf_remains(&keyseq, 0) == 0)
367 break; /* Not freeing the last key structure */
369 safe_syncbuf (&subbuf, &keyseq, seq_buflen);
373 * There could be other data inside the outermost sequence ... tags we don't
374 * know about. So, not invoking "safe_syncbuf(&buf,&subbuf)"
380 for (i = 0; i < *n_key_data; i++) {
381 free ((*out)[i].key_data_contents[0]);
382 free ((*out)[i].key_data_contents[1]);