1 #pragma ident	"%Z%%M%	%I%	%E% SMI"
2 
3 /*
4  * src/lib/krb5/asn.1/krb5_encode.c
5  *
6  * Copyright 1994 by the Massachusetts Institute of Technology.
7  * All Rights Reserved.
8  *
9  * Export of this software from the United States of America may
10  *   require a specific license from the United States Government.
11  *   It is the responsibility of any person or organization contemplating
12  *   export to obtain such a license before exporting.
13  *
14  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
15  * distribute this software and its documentation for any purpose and
16  * without fee is hereby granted, provided that the above copyright
17  * notice appear in all copies and that both that copyright notice and
18  * this permission notice appear in supporting documentation, and that
19  * the name of M.I.T. not be used in advertising or publicity pertaining
20  * to distribution of the software without specific, written prior
21  * permission.  Furthermore if you modify this software you must label
22  * your software as modified software and not distribute it in such a
23  * fashion that it might be confused with the original M.I.T. software.
24  * M.I.T. makes no representations about the suitability of
25  * this software for any purpose.  It is provided "as is" without express
26  * or implied warranty.
27  */
28 
29 #include "krb5.h"
30 #include "asn1_k_encode.h"
31 #include "asn1_encode.h"
32 #include "krbasn1.h"
33 #include "asn1buf.h"
34 #include "asn1_make.h"
35 
36 /**************** Macros (these save a lot of typing) ****************/
37 
38 /**** krb5 macros ****/
39 #if 0
40    How to write a krb5 encoder function using these macros:
41 
42    asn1_error_code encode_krb5_structure(const krb5_type *rep,
43                                          krb5_data **code)
44    {
45      krb5_setup();
46 
47      krb5_addfield(rep->last_field, n, asn1_type);
48      krb5_addfield(rep->next_to_last_field, n-1, asn1_type);
49      ...
50 
51      /* for OPTIONAL fields */
52      if(rep->field_i == should_not_be_omitted)
53        krb5_addfield(rep->field_i, i, asn1_type);
54 
55      /* for string fields (these encoders take an additional argument,
56 	the length of the string) */
57      addlenfield(rep->field_length, rep->field, i-1, asn1_type);
58 
59      /* if you really have to do things yourself... */
60      retval = asn1_encode_asn1_type(buf,rep->field,&length);
61      if(retval) return retval;
62      sum += length;
63      retval = asn1_make_etag(buf,
64 			    [UNIVERSAL/APPLICATION/CONTEXT_SPECIFIC/PRIVATE],
65 			    tag_number, length, &length);
66      if(retval) return retval;
67      sum += length;
68 
69      ...
70      krb5_addfield(rep->second_field, 1, asn1_type);
71      krb5_addfield(rep->first_field, 0, asn1_type);
72      krb5_makeseq();
73      krb5_apptag(tag_number);
74 
75      krb5_cleanup();
76    }
77 #endif
78 
79 /* setup() -- create and initialize bookkeeping variables
80      retval: stores error codes returned from subroutines
81      buf: the coding buffer
82      length: length of the most-recently produced encoding
83      sum: cumulative length of the entire encoding */
84 #define krb5_setup()\
85   asn1_error_code retval;\
86   asn1buf *buf=NULL;\
87   unsigned int length, sum=0;\
88 \
89   if(rep == NULL) return ASN1_MISSING_FIELD;\
90 \
91   retval = asn1buf_create(&buf);\
92   if(retval) return retval
93 
94 /* krb5_addfield -- add a field, or component, to the encoding */
95 #define krb5_addfield(value,tag,encoder)\
96 { retval = encoder(buf,value,&length);\
97   if(retval){\
98     asn1buf_destroy(&buf);\
99     return retval; }\
100   sum += length;\
101   retval = asn1_make_etag(buf,CONTEXT_SPECIFIC,tag,length,&length);\
102   if(retval){\
103     asn1buf_destroy(&buf);\
104     return retval; }\
105   sum += length; }
106 
107 /* krb5_addlenfield -- add a field whose length must be separately specified */
108 #define krb5_addlenfield(len,value,tag,encoder)\
109 { retval = encoder(buf,len,value,&length);\
110   if(retval){\
111     asn1buf_destroy(&buf);\
112     return retval; }\
113   sum += length;\
114   retval = asn1_make_etag(buf,CONTEXT_SPECIFIC,tag,length,&length);\
115   if(retval){\
116     asn1buf_destroy(&buf);\
117     return retval; }\
118   sum += length; }
119 
120 /* form a sequence (by adding a sequence header to the current encoding) */
121 #define krb5_makeseq()\
122   retval = asn1_make_sequence(buf,sum,&length);\
123   if(retval){\
124     asn1buf_destroy(&buf);\
125     return retval; }\
126   sum += length
127 
128 /* add an APPLICATION class tag to the current encoding */
129 #define krb5_apptag(num)\
130   retval = asn1_make_etag(buf,APPLICATION,num,sum,&length);\
131   if(retval){\
132     asn1buf_destroy(&buf);\
133     return retval; }\
134   sum += length
135 
136 /* produce the final output and clean up the workspace */
137 #define krb5_cleanup()\
138   retval = asn12krb5_buf(buf,code);\
139   if(retval){\
140     asn1buf_destroy(&buf);\
141     return retval; }\
142   retval = asn1buf_destroy(&buf);\
143   if(retval){\
144     return retval; }\
145 \
146   return 0
147 
148 krb5_error_code encode_krb5_authenticator(const krb5_authenticator *rep, krb5_data **code)
149 {
150   krb5_setup();
151 
152   /* authorization-data[8]	AuthorizationData OPTIONAL */
153   if(rep->authorization_data != NULL &&
154      rep->authorization_data[0] != NULL){
155     retval = asn1_encode_authorization_data(buf, (const krb5_authdata **)
156 					    rep->authorization_data,
157 					    &length);
158     if(retval){
159       asn1buf_destroy(&buf);
160       return retval; }
161     sum += length;
162     retval = asn1_make_etag(buf,CONTEXT_SPECIFIC,8,length,&length);
163     if(retval){
164       asn1buf_destroy(&buf);
165       return retval; }
166     sum += length;
167   }
168 
169   /* seq-number[7]		INTEGER OPTIONAL */
170   if(rep->seq_number != 0)
171     krb5_addfield(rep->seq_number,7,asn1_encode_unsigned_integer);
172 
173   /* subkey[6]			EncryptionKey OPTIONAL */
174   if(rep->subkey != NULL)
175     krb5_addfield(rep->subkey,6,asn1_encode_encryption_key);
176 
177   /* ctime[5]			KerberosTime */
178   krb5_addfield(rep->ctime,5,asn1_encode_kerberos_time);
179 
180   /* cusec[4]			INTEGER */
181   krb5_addfield(rep->cusec,4,asn1_encode_integer);
182 
183   /* cksum[3]			Checksum OPTIONAL */
184   if(rep->checksum != NULL)
185     krb5_addfield(rep->checksum,3,asn1_encode_checksum);
186 
187   /* cname[2]			PrincipalName */
188   krb5_addfield(rep->client,2,asn1_encode_principal_name);
189 
190   /* crealm[1]			Realm */
191   krb5_addfield(rep->client,1,asn1_encode_realm);
192 
193   /* authenticator-vno[0]	INTEGER */
194   krb5_addfield(KVNO,0,asn1_encode_integer);
195 
196   /* Authenticator ::= [APPLICATION 2] SEQUENCE */
197   krb5_makeseq();
198   krb5_apptag(2);
199 
200   krb5_cleanup();
201 }
202 
203 krb5_error_code encode_krb5_ticket(const krb5_ticket *rep, krb5_data **code)
204 {
205   krb5_setup();
206 
207   /* enc-part[3]	EncryptedData */
208   krb5_addfield(&(rep->enc_part),3,asn1_encode_encrypted_data);
209 
210   /* sname [2]		PrincipalName */
211   krb5_addfield(rep->server,2,asn1_encode_principal_name);
212 
213   /* realm [1]		Realm */
214   krb5_addfield(rep->server,1,asn1_encode_realm);
215 
216   /* tkt-vno [0]	INTEGER */
217   krb5_addfield(KVNO,0,asn1_encode_integer);
218 
219   /* Ticket ::= [APPLICATION 1] SEQUENCE */
220   krb5_makeseq();
221   krb5_apptag(1);
222 
223   krb5_cleanup();
224 }
225 
226 krb5_error_code encode_krb5_encryption_key(const krb5_keyblock *rep, krb5_data **code)
227 {
228   krb5_setup();
229 
230   /* keyvalue[1]	OCTET STRING */
231   krb5_addlenfield(rep->length,rep->contents,1,asn1_encode_octetstring);
232 
233   /* enctype[0]		INTEGER */
234   krb5_addfield(rep->enctype,0,asn1_encode_integer);
235 
236   /* EncryptionKey ::= SEQUENCE */
237   krb5_makeseq();
238 
239   krb5_cleanup();
240 }
241 
242 krb5_error_code encode_krb5_enc_tkt_part(const krb5_enc_tkt_part *rep, krb5_data **code)
243 {
244   krb5_setup();
245 
246   /* authorization-data[10]	AuthorizationData OPTIONAL */
247   if(rep->authorization_data != NULL &&
248      rep->authorization_data[0] != NULL)
249     krb5_addfield((const krb5_authdata**)rep->authorization_data,
250 		  10,asn1_encode_authorization_data);
251 
252   /* caddr[9]			HostAddresses OPTIONAL */
253   if(rep->caddrs != NULL && rep->caddrs[0] != NULL)
254     krb5_addfield((const krb5_address**)rep->caddrs,9,asn1_encode_host_addresses);
255 
256   /* renew-till[8]		KerberosTime OPTIONAL */
257   if(rep->times.renew_till)
258     krb5_addfield(rep->times.renew_till,8,asn1_encode_kerberos_time);
259 
260   /* endtime[7]			KerberosTime */
261   krb5_addfield(rep->times.endtime,7,asn1_encode_kerberos_time);
262 
263   /* starttime[6]		KerberosTime OPTIONAL */
264   if(rep->times.starttime)
265     krb5_addfield(rep->times.starttime,6,asn1_encode_kerberos_time);
266 
267   /* authtime[5]		KerberosTime */
268   krb5_addfield(rep->times.authtime,5,asn1_encode_kerberos_time);
269 
270   /* transited[4]		TransitedEncoding */
271   krb5_addfield(&(rep->transited),4,asn1_encode_transited_encoding);
272 
273   /* cname[3]			PrincipalName */
274   krb5_addfield(rep->client,3,asn1_encode_principal_name);
275 
276   /* crealm[2]			Realm */
277   krb5_addfield(rep->client,2,asn1_encode_realm);
278 
279   /* key[1]			EncryptionKey */
280   krb5_addfield(rep->session,1,asn1_encode_encryption_key);
281 
282   /* flags[0]			TicketFlags */
283   krb5_addfield(rep->flags,0,asn1_encode_ticket_flags);
284 
285   /* EncTicketPart ::= [APPLICATION 3] SEQUENCE */
286   krb5_makeseq();
287   krb5_apptag(3);
288 
289   krb5_cleanup();
290 }
291 
292 krb5_error_code encode_krb5_enc_kdc_rep_part(const krb5_enc_kdc_rep_part *rep, krb5_data **code)
293 {
294   asn1_error_code retval;
295   asn1buf *buf=NULL;
296   unsigned int length, sum=0;
297 
298   if(rep == NULL) return ASN1_MISSING_FIELD;
299 
300   retval = asn1buf_create(&buf);
301   if(retval) return retval;
302 
303   retval = asn1_encode_enc_kdc_rep_part(buf,rep,&length);
304   if(retval) return retval;
305   sum += length;
306 
307 #ifdef KRB5_ENCKRB5KDCREPPART_COMPAT
308   krb5_apptag(26);
309 #else
310   /* XXX WRONG!!! Should use 25 || 26, not the outer KDC_REP tags! */
311   if (rep->msg_type == KRB5_AS_REP) { krb5_apptag(ASN1_KRB_AS_REP); }
312   else if (rep->msg_type == KRB5_TGS_REP) { krb5_apptag(ASN1_KRB_TGS_REP); }
313   else return KRB5_BADMSGTYPE;
314 #endif
315   krb5_cleanup();
316 }
317 
318 /* yes, the translation is identical to that used for KDC__REP */
319 krb5_error_code encode_krb5_as_rep(const krb5_kdc_rep *rep, krb5_data **code)
320 {
321   krb5_setup();
322 
323   /* AS-REP ::= [APPLICATION 11] KDC-REP */
324   retval = asn1_encode_kdc_rep(KRB5_AS_REP,buf,rep,&length);
325   if(retval) return retval;
326   sum += length;
327 
328   krb5_apptag(11);
329 
330   krb5_cleanup();
331 }
332 
333 /* yes, the translation is identical to that used for KDC__REP */
334 krb5_error_code encode_krb5_tgs_rep(const krb5_kdc_rep *rep, krb5_data **code)
335 {
336   krb5_setup();
337 
338   /* TGS-REP ::= [APPLICATION 13] KDC-REP */
339   retval = asn1_encode_kdc_rep(KRB5_TGS_REP,buf,rep,&length);
340   if(retval) return retval;
341   sum += length;
342 
343   krb5_apptag(13);
344 
345   krb5_cleanup();
346 }
347 
348 krb5_error_code encode_krb5_ap_req(const krb5_ap_req *rep, krb5_data **code)
349 {
350   krb5_setup();
351 
352   /* authenticator[4]	EncryptedData */
353   krb5_addfield(&(rep->authenticator),4,asn1_encode_encrypted_data);
354 
355   /* ticket[3]		Ticket */
356   krb5_addfield(rep->ticket,3,asn1_encode_ticket);
357 
358   /* ap-options[2]	APOptions */
359   krb5_addfield(rep->ap_options,2,asn1_encode_ap_options);
360 
361   /* msg-type[1]	INTEGER */
362   krb5_addfield(ASN1_KRB_AP_REQ,1,asn1_encode_integer);
363 
364   /* pvno[0]		INTEGER */
365   krb5_addfield(KVNO,0,asn1_encode_integer);
366 
367   /* AP-REQ ::=	[APPLICATION 14] SEQUENCE */
368   krb5_makeseq();
369   krb5_apptag(14);
370 
371   krb5_cleanup();
372 }
373 
374 krb5_error_code encode_krb5_ap_rep(const krb5_ap_rep *rep, krb5_data **code)
375 {
376   krb5_setup();
377 
378   /* enc-part[2]	EncryptedData */
379   krb5_addfield(&(rep->enc_part),2,asn1_encode_encrypted_data);
380 
381   /* msg-type[1]	INTEGER */
382   krb5_addfield(ASN1_KRB_AP_REP,1,asn1_encode_integer);
383 
384   /* pvno[0]		INTEGER */
385   krb5_addfield(KVNO,0,asn1_encode_integer);
386 
387   /* AP-REP ::=	[APPLICATION 15] SEQUENCE */
388   krb5_makeseq();
389   krb5_apptag(15);
390 
391   krb5_cleanup();
392 }
393 
394 
395 krb5_error_code encode_krb5_ap_rep_enc_part(const krb5_ap_rep_enc_part *rep, krb5_data **code)
396 {
397   krb5_setup();
398 
399   /* seq-number[3]	INTEGER OPTIONAL */
400   if(rep->seq_number)
401     krb5_addfield(rep->seq_number,3,asn1_encode_unsigned_integer);
402 
403   /* subkey[2]		EncryptionKey OPTIONAL */
404   if(rep->subkey != NULL)
405     krb5_addfield(rep->subkey,2,asn1_encode_encryption_key);
406 
407   /* cusec[1]		INTEGER */
408   krb5_addfield(rep->cusec,1,asn1_encode_integer);
409 
410   /* ctime[0]		KerberosTime */
411   krb5_addfield(rep->ctime,0,asn1_encode_kerberos_time);
412 
413   /* EncAPRepPart ::= [APPLICATION 27] SEQUENCE */
414   krb5_makeseq();
415   krb5_apptag(27);
416 
417   krb5_cleanup();
418 }
419 
420 krb5_error_code encode_krb5_as_req(const krb5_kdc_req *rep, krb5_data **code)
421 {
422   krb5_setup();
423 
424   /* AS-REQ ::= [APPLICATION 10] KDC-REQ */
425   retval = asn1_encode_kdc_req(KRB5_AS_REQ,buf,rep,&length);
426   if(retval) return retval;
427   sum += length;
428 
429   krb5_apptag(10);
430 
431   krb5_cleanup();
432 }
433 
434 krb5_error_code encode_krb5_tgs_req(const krb5_kdc_req *rep, krb5_data **code)
435 {
436   krb5_setup();
437 
438   /* TGS-REQ ::= [APPLICATION 12] KDC-REQ */
439   retval = asn1_encode_kdc_req(KRB5_TGS_REQ,buf,rep,&length);
440   if(retval) return retval;
441   sum += length;
442 
443   krb5_apptag(12);
444 
445   krb5_cleanup();
446 }
447 
448 krb5_error_code encode_krb5_kdc_req_body(const krb5_kdc_req *rep, krb5_data **code)
449 {
450   krb5_setup();
451 
452   retval = asn1_encode_kdc_req_body(buf,rep,&length);
453   if(retval) return retval;
454   sum += length;
455 
456   krb5_cleanup();
457 }
458 
459 
460 krb5_error_code encode_krb5_safe(const krb5_safe *rep, krb5_data **code)
461 {
462   krb5_setup();
463 
464   /* cksum[3]		Checksum */
465   krb5_addfield(rep->checksum,3,asn1_encode_checksum);
466 
467   /* safe-body[2]	KRB-SAFE-BODY */
468   krb5_addfield(rep,2,asn1_encode_krb_safe_body);
469 
470   /* msg-type[1]	INTEGER */
471   krb5_addfield(ASN1_KRB_SAFE,1,asn1_encode_integer);
472 
473   /* pvno[0]		INTEGER */
474   krb5_addfield(KVNO,0,asn1_encode_integer);
475 
476   /* KRB-SAFE ::= [APPLICATION 20] SEQUENCE */
477   krb5_makeseq();
478   krb5_apptag(20);
479 
480   krb5_cleanup();
481 }
482 
483 /*
484  * encode_krb5_safe_with_body
485  *
486  * Like encode_krb5_safe(), except takes a saved KRB-SAFE-BODY
487  * encoding to avoid problems with re-encoding.
488  */
489 krb5_error_code encode_krb5_safe_with_body(
490   const krb5_safe *rep,
491   const krb5_data *body,
492   krb5_data **code)
493 {
494   krb5_setup();
495 
496   if (body == NULL) {
497       asn1buf_destroy(&buf);
498       return ASN1_MISSING_FIELD;
499   }
500 
501   /* cksum[3]		Checksum */
502   krb5_addfield(rep->checksum,3,asn1_encode_checksum);
503 
504   /* safe-body[2]	KRB-SAFE-BODY */
505   krb5_addfield(body,2,asn1_encode_krb_saved_safe_body);
506 
507   /* msg-type[1]	INTEGER */
508   krb5_addfield(ASN1_KRB_SAFE,1,asn1_encode_integer);
509 
510   /* pvno[0]		INTEGER */
511   krb5_addfield(KVNO,0,asn1_encode_integer);
512 
513   /* KRB-SAFE ::= [APPLICATION 20] SEQUENCE */
514   krb5_makeseq();
515   krb5_apptag(20);
516 
517   krb5_cleanup();
518 }
519 
520 krb5_error_code encode_krb5_priv(const krb5_priv *rep, krb5_data **code)
521 {
522   krb5_setup();
523 
524   /* enc-part[3]	EncryptedData */
525   krb5_addfield(&(rep->enc_part),3,asn1_encode_encrypted_data);
526 
527   /* msg-type[1]	INTEGER */
528   krb5_addfield(ASN1_KRB_PRIV,1,asn1_encode_integer);
529 
530   /* pvno[0]		INTEGER */
531   krb5_addfield(KVNO,0,asn1_encode_integer);
532 
533   /* KRB-PRIV ::= [APPLICATION 21] SEQUENCE */
534   krb5_makeseq();
535   krb5_apptag(21);
536 
537   krb5_cleanup();
538 }
539 
540 krb5_error_code encode_krb5_enc_priv_part(const krb5_priv_enc_part *rep, krb5_data **code)
541 {
542   krb5_setup();
543 
544   /* r-address[5]	HostAddress OPTIONAL -- recip's addr */
545   if(rep->r_address)
546     krb5_addfield(rep->r_address,5,asn1_encode_host_address);
547 
548   /* s-address[4]	HostAddress -- sender's addr */
549   krb5_addfield(rep->s_address,4,asn1_encode_host_address);
550 
551   /* seq-number[3]	INTEGER OPTIONAL */
552   if(rep->seq_number)
553     krb5_addfield(rep->seq_number,3,asn1_encode_unsigned_integer);
554 
555   /* usec[2]		INTEGER OPTIONAL */
556   if(rep->timestamp){
557     krb5_addfield(rep->usec,2,asn1_encode_integer);
558     /* timestamp[1]	KerberosTime OPTIONAL */
559     krb5_addfield(rep->timestamp,1,asn1_encode_kerberos_time);
560   }
561 
562   /* user-data[0]	OCTET STRING */
563   krb5_addlenfield(rep->user_data.length,rep->user_data.data,0,asn1_encode_charstring);
564 
565   /* EncKrbPrivPart ::= [APPLICATION 28] SEQUENCE */
566   krb5_makeseq();
567   krb5_apptag(28);
568 
569   krb5_cleanup();
570 }
571 
572 krb5_error_code encode_krb5_cred(const krb5_cred *rep, krb5_data **code)
573 {
574   krb5_setup();
575 
576   /* enc-part[3]	EncryptedData */
577   krb5_addfield(&(rep->enc_part),3,asn1_encode_encrypted_data);
578 
579   /* tickets[2]		SEQUENCE OF Ticket */
580   krb5_addfield((const krb5_ticket**)rep->tickets,2,asn1_encode_sequence_of_ticket);
581 
582   /* msg-type[1]	INTEGER, -- KRB_CRED */
583   krb5_addfield(ASN1_KRB_CRED,1,asn1_encode_integer);
584 
585   /* pvno[0]		INTEGER */
586   krb5_addfield(KVNO,0,asn1_encode_integer);
587 
588   /* KRB-CRED ::= [APPLICATION 22] SEQUENCE */
589   krb5_makeseq();
590   krb5_apptag(22);
591 
592   krb5_cleanup();
593 }
594 
595 krb5_error_code encode_krb5_enc_cred_part(const krb5_cred_enc_part *rep, krb5_data **code)
596 {
597   krb5_setup();
598 
599   /* r-address[5]	HostAddress OPTIONAL */
600   if(rep->r_address != NULL)
601     krb5_addfield(rep->r_address,5,asn1_encode_host_address);
602 
603   /* s-address[4]	HostAddress OPTIONAL */
604   if(rep->s_address != NULL)
605     krb5_addfield(rep->s_address,4,asn1_encode_host_address);
606 
607   /* usec[3]		INTEGER OPTIONAL */
608   if(rep->timestamp){
609     krb5_addfield(rep->usec,3,asn1_encode_integer);
610     /* timestamp[2]	KerberosTime OPTIONAL */
611     krb5_addfield(rep->timestamp,2,asn1_encode_kerberos_time);
612   }
613 
614   /* nonce[1]		INTEGER OPTIONAL */
615   if(rep->nonce)
616     krb5_addfield(rep->nonce,1,asn1_encode_integer);
617 
618   /* ticket-info[0]	SEQUENCE OF KrbCredInfo */
619   krb5_addfield((const krb5_cred_info**)rep->ticket_info,
620 		0,asn1_encode_sequence_of_krb_cred_info);
621 
622   /* EncKrbCredPart ::= [APPLICATION 29] SEQUENCE */
623   krb5_makeseq();
624   krb5_apptag(29);
625 
626   krb5_cleanup();
627 }
628 
629 krb5_error_code encode_krb5_error(const krb5_error *rep, krb5_data **code)
630 {
631   krb5_setup();
632 
633   /* e-data[12]		OCTET STRING OPTIONAL */
634   if(rep->e_data.data != NULL && rep->e_data.length > 0)
635     krb5_addlenfield(rep->e_data.length,rep->e_data.data,12,asn1_encode_charstring);
636 
637   /* e-text[11]		GeneralString OPTIONAL */
638   if(rep->text.data != NULL && rep->text.length > 0)
639     krb5_addlenfield(rep->text.length,rep->text.data,11,asn1_encode_generalstring);
640 
641   /* sname[10]		PrincipalName -- Correct name */
642   krb5_addfield(rep->server,10,asn1_encode_principal_name);
643 
644   /* realm[9]		Realm -- Correct realm */
645   krb5_addfield(rep->server,9,asn1_encode_realm);
646 
647   /* cname[8]		PrincipalName OPTIONAL */
648   if(rep->client != NULL){
649     krb5_addfield(rep->client,8,asn1_encode_principal_name);
650     /* crealm[7]		Realm OPTIONAL */
651     krb5_addfield(rep->client,7,asn1_encode_realm);
652   }
653 
654   /* error-code[6]	INTEGER */
655   krb5_addfield(rep->error,6,asn1_encode_ui_4);
656 
657   /* susec[5]		INTEGER */
658   krb5_addfield(rep->susec,5,asn1_encode_integer);
659 
660   /* stime[4]		KerberosTime */
661   krb5_addfield(rep->stime,4,asn1_encode_kerberos_time);
662 
663   /* cusec[3]		INTEGER OPTIONAL */
664   if(rep->cusec)
665     krb5_addfield(rep->cusec,3,asn1_encode_integer);
666 
667   /* ctime[2]		KerberosTime OPTIONAL */
668   if(rep->ctime)
669     krb5_addfield(rep->ctime,2,asn1_encode_kerberos_time);
670 
671   /* msg-type[1]	INTEGER */
672   krb5_addfield(ASN1_KRB_ERROR,1,asn1_encode_integer);
673 
674   /* pvno[0]		INTEGER */
675   krb5_addfield(KVNO,0,asn1_encode_integer);
676 
677   /* KRB-ERROR ::= [APPLICATION 30] SEQUENCE */
678   krb5_makeseq();
679   krb5_apptag(30);
680 
681   krb5_cleanup();
682 }
683 
684 krb5_error_code encode_krb5_authdata(const krb5_authdata **rep, krb5_data **code)
685 {
686   asn1_error_code retval;
687   asn1buf *buf=NULL;
688   unsigned int length;
689 
690   if(rep == NULL) return ASN1_MISSING_FIELD;
691 
692   retval = asn1buf_create(&buf);
693   if(retval) return retval;
694 
695   retval = asn1_encode_authorization_data(buf,(const krb5_authdata**)rep,
696 					  &length);
697   if(retval) return retval;
698 
699   krb5_cleanup();
700 }
701 
702 krb5_error_code encode_krb5_alt_method(const krb5_alt_method *rep, krb5_data **code)
703 {
704   krb5_setup();
705 
706   /* method-data[1]		OctetString OPTIONAL */
707   if(rep->data != NULL && rep->length > 0)
708     krb5_addlenfield(rep->length,rep->data,1,asn1_encode_octetstring);
709 
710   /* method-type[0]		Integer */
711   krb5_addfield(rep->method,0,asn1_encode_integer);
712 
713   krb5_makeseq();
714 
715   krb5_cleanup();
716 }
717 
718 krb5_error_code encode_krb5_etype_info(const krb5_etype_info_entry **rep, krb5_data **code)
719 {
720   krb5_setup();
721   retval = asn1_encode_etype_info(buf,rep,&length, 0);
722   if(retval) return retval;
723   sum += length;
724   krb5_cleanup();
725 }
726 
727 krb5_error_code encode_krb5_etype_info2(const krb5_etype_info_entry **rep, krb5_data **code)
728 {
729   krb5_setup();
730   retval = asn1_encode_etype_info(buf,rep,&length, 1);
731   if(retval) return retval;
732   sum += length;
733   krb5_cleanup();
734 }
735 
736 
737 krb5_error_code encode_krb5_enc_data(const krb5_enc_data *rep, krb5_data **code)
738 {
739   krb5_setup();
740 
741   retval = asn1_encode_encrypted_data(buf,rep,&length);
742   if(retval) return retval;
743   sum += length;
744 
745   krb5_cleanup();
746 }
747 
748 krb5_error_code encode_krb5_pa_enc_ts(const krb5_pa_enc_ts *rep, krb5_data **code)
749 {
750   krb5_setup();
751 
752   /* pausec[1]                    INTEGER OPTIONAL */
753   if (rep->pausec)
754 	  krb5_addfield(rep->pausec,1,asn1_encode_integer);
755 
756   /* patimestamp[0]               KerberosTime, -- client's time */
757   krb5_addfield(rep->patimestamp,0,asn1_encode_kerberos_time);
758 
759   krb5_makeseq();
760 
761   krb5_cleanup();
762 }
763 
764 /* Sandia Additions */
765 krb5_error_code encode_krb5_pwd_sequence(const passwd_phrase_element *rep, krb5_data **code)
766 {
767   krb5_setup();
768   retval = asn1_encode_passwdsequence(buf,rep,&length);
769   if(retval) return retval;
770   sum += length;
771   krb5_cleanup();
772 }
773 
774 krb5_error_code encode_krb5_pwd_data(const krb5_pwd_data *rep, krb5_data **code)
775 {
776   krb5_setup();
777   krb5_addfield((const passwd_phrase_element**)rep->element,1,asn1_encode_sequence_of_passwdsequence);
778   krb5_addfield(rep->sequence_count,0,asn1_encode_integer);
779   krb5_makeseq();
780   krb5_cleanup();
781 }
782 
783 krb5_error_code encode_krb5_padata_sequence(const krb5_pa_data **rep, krb5_data **code)
784 {
785   krb5_setup();
786 
787   retval = asn1_encode_sequence_of_pa_data(buf,rep,&length);
788   if(retval) return retval;
789   sum += length;
790 
791   krb5_cleanup();
792 }
793 
794 /* sam preauth additions */
795 krb5_error_code encode_krb5_sam_challenge(const krb5_sam_challenge *rep, krb5_data **code)
796 {
797   krb5_setup();
798   retval = asn1_encode_sam_challenge(buf,rep,&length);
799   if(retval) return retval;
800   sum += length;
801   krb5_cleanup();
802 }
803 
804 krb5_error_code encode_krb5_sam_challenge_2(const krb5_sam_challenge_2 *rep, krb5_data **code)
805 {
806   krb5_setup();
807   retval = asn1_encode_sam_challenge_2(buf,rep,&length);
808   if(retval) return retval;
809   sum += length;
810   krb5_cleanup();
811 }
812 
813 krb5_error_code encode_krb5_sam_challenge_2_body(const krb5_sam_challenge_2_body *rep, krb5_data **code)
814 {
815   krb5_setup();
816   retval = asn1_encode_sam_challenge_2_body(buf,rep,&length);
817   if(retval) return retval;
818   sum += length;
819   krb5_cleanup();
820 }
821 
822 krb5_error_code encode_krb5_sam_key(const krb5_sam_key *rep, krb5_data **code)
823 {
824   krb5_setup();
825   retval = asn1_encode_sam_key(buf,rep,&length);
826   if(retval) return retval;
827   sum += length;
828   krb5_cleanup();
829 }
830 
831 krb5_error_code encode_krb5_enc_sam_response_enc(const krb5_enc_sam_response_enc *rep, krb5_data **code)
832 {
833   krb5_setup();
834   retval = asn1_encode_enc_sam_response_enc(buf,rep,&length);
835   if(retval) return retval;
836   sum += length;
837   krb5_cleanup();
838 }
839 
840 krb5_error_code encode_krb5_enc_sam_response_enc_2(const krb5_enc_sam_response_enc_2 *rep, krb5_data **code)
841 {
842   krb5_setup();
843   retval = asn1_encode_enc_sam_response_enc_2(buf,rep,&length);
844   if(retval) return retval;
845   sum += length;
846   krb5_cleanup();
847 }
848 
849 krb5_error_code encode_krb5_sam_response(const krb5_sam_response *rep, krb5_data **code)
850 {
851   krb5_setup();
852   retval = asn1_encode_sam_response(buf,rep,&length);
853   if(retval) return retval;
854   sum += length;
855   krb5_cleanup();
856 }
857 
858 krb5_error_code encode_krb5_sam_response_2(const krb5_sam_response_2 *rep, krb5_data **code)
859 {
860   krb5_setup();
861   retval = asn1_encode_sam_response_2(buf,rep,&length);
862   if(retval) return retval;
863   sum += length;
864   krb5_cleanup();
865 }
866 
867 krb5_error_code encode_krb5_predicted_sam_response(const krb5_predicted_sam_response *rep, krb5_data **code)
868 {
869   krb5_setup();
870   retval = asn1_encode_predicted_sam_response(buf,rep,&length);
871   if(retval) return retval;
872   sum += length;
873   krb5_cleanup();
874 }
875 
876 krb5_error_code encode_krb5_setpw_req(const krb5_principal target,
877 				      char *password, krb5_data **code)
878 {
879   /* Macros really want us to have a variable called rep which we do not need*/
880   const char *rep = "dummy string";
881 
882   krb5_setup();
883 
884   krb5_addfield(target,2,asn1_encode_realm);
885   krb5_addfield(target,1,asn1_encode_principal_name);
886   krb5_addlenfield(strlen(password), (const uchar_t *)password,0,asn1_encode_octetstring);
887   krb5_makeseq();
888 
889 
890   krb5_cleanup();
891 }
892