dc85fdf27696dd8333adc0a271322e90794d42b5
[krb5.git] / src / lib / krb5 / asn.1 / krb5_encode.c
1 /*
2  * src/lib/krb5/asn.1/krb5_encode.c
3  * 
4  * Copyright 1994 by the Massachusetts Institute of Technology.
5  * All Rights Reserved.
6  *
7  * Export of this software from the United States of America may
8  *   require a specific license from the United States Government.
9  *   It is the responsibility of any person or organization contemplating
10  *   export to obtain such a license before exporting.
11  * 
12  * WITHIN THAT CONSTRAINT, permission to use, copy, modify, and
13  * distribute this software and its documentation for any purpose and
14  * without fee is hereby granted, provided that the above copyright
15  * notice appear in all copies and that both that copyright notice and
16  * this permission notice appear in supporting documentation, and that
17  * the name of M.I.T. not be used in advertising or publicity pertaining
18  * to distribution of the software without specific, written prior
19  * permission.  M.I.T. makes no representations about the suitability of
20  * this software for any purpose.  It is provided "as is" without express
21  * or implied warranty.
22  */
23
24 #include "krb5.h"
25 #include "asn1_k_encode.h"
26 #include "asn1_encode.h"
27 #include "krbasn1.h"
28 #include "asn1buf.h"
29 #include "asn1_make.h"
30
31 /**************** Macros (these save a lot of typing) ****************/
32
33 /**** krb5 macros ****/
34 #if 0
35    How to write a krb5 encoder function using these macros:
36
37    asn1_error_code encode_krb5_structure(const krb5_type *rep,
38                                          krb5_data **code)
39    {
40      krb5_setup();
41
42      krb5_addfield(rep->last_field, n, asn1_type);
43      krb5_addfield(rep->next_to_last_field, n-1, asn1_type);
44      ...
45
46      /* for OPTIONAL fields */
47      if(rep->field_i == should_not_be_omitted)
48        krb5_addfield(rep->field_i, i, asn1_type);
49
50      /* for string fields (these encoders take an additional argument,
51         the length of the string) */
52      addlenfield(rep->field_length, rep->field, i-1, asn1_type);
53
54      /* if you really have to do things yourself... */
55      retval = asn1_encode_asn1_type(buf,rep->field,&length);
56      if(retval) return retval;
57      sum += length;
58      retval = asn1_make_etag(buf,
59                             [UNIVERSAL/APPLICATION/CONTEXT_SPECIFIC/PRIVATE],
60                             tag_number, length, &length);
61      if(retval) return retval;
62      sum += length;
63
64      ...
65      krb5_addfield(rep->second_field, 1, asn1_type);
66      krb5_addfield(rep->first_field, 0, asn1_type);
67      krb5_makeseq();
68      krb5_apptag(tag_number);
69
70      krb5_cleanup();
71    }
72 #endif
73
74 /* setup() -- create and initialize bookkeeping variables
75      retval: stores error codes returned from subroutines
76      buf: the coding buffer
77      length: length of the most-recently produced encoding
78      sum: cumulative length of the entire encoding */
79 #define krb5_setup()\
80   asn1_error_code retval;\
81   asn1buf *buf=NULL;\
82   int length, sum=0;\
83 \
84   if(rep == NULL) return ASN1_MISSING_FIELD;\
85 \
86   retval = asn1buf_create(&buf);\
87   if(retval) return retval
88   
89 /* krb5_addfield -- add a field, or component, to the encoding */
90 #define krb5_addfield(value,tag,encoder)\
91 { retval = encoder(buf,value,&length);\
92   if(retval){\
93     asn1buf_destroy(&buf);\
94     return retval; }\
95   sum += length;\
96   retval = asn1_make_etag(buf,CONTEXT_SPECIFIC,tag,length,&length);\
97   if(retval){\
98     asn1buf_destroy(&buf);\
99     return retval; }\
100   sum += length; }
101
102 /* krb5_addlenfield -- add a field whose length must be separately specified */
103 #define krb5_addlenfield(len,value,tag,encoder)\
104 { retval = encoder(buf,len,value,&length);\
105   if(retval){\
106     asn1buf_destroy(&buf);\
107     return retval; }\
108   sum += length;\
109   retval = asn1_make_etag(buf,CONTEXT_SPECIFIC,tag,length,&length);\
110   if(retval){\
111     asn1buf_destroy(&buf);\
112     return retval; }\
113   sum += length; }
114
115 /* form a sequence (by adding a sequence header to the current encoding) */
116 #define krb5_makeseq()\
117   retval = asn1_make_sequence(buf,sum,&length);\
118   if(retval){\
119     asn1buf_destroy(&buf);\
120     return retval; }\
121   sum += length
122
123 /* add an APPLICATION class tag to the current encoding */
124 #define krb5_apptag(num)\
125   retval = asn1_make_etag(buf,APPLICATION,num,sum,&length);\
126   if(retval){\
127     asn1buf_destroy(&buf);\
128     return retval; }\
129   sum += length
130
131 /* produce the final output and clean up the workspace */
132 #define krb5_cleanup()\
133   retval = asn12krb5_buf(buf,code);\
134   if(retval){\
135     asn1buf_destroy(&buf);\
136     return retval; }\
137   retval = asn1buf_destroy(&buf);\
138   if(retval){\
139     asn1buf_destroy(&buf);\
140     return retval; }\
141 \
142   return 0
143
144 krb5_error_code INTERFACE encode_krb5_authenticator(rep, code)
145      const krb5_authenticator * rep;
146      krb5_data ** code;
147 {
148   krb5_setup();
149
150   /* authorization-data[8]      AuthorizationData OPTIONAL */
151   if(rep->authorization_data != NULL &&
152      rep->authorization_data[0] != NULL){
153     retval = asn1_encode_authorization_data(buf, (const krb5_authdata **)
154                                             rep->authorization_data,
155                                             &length);
156     if(retval){
157       asn1buf_destroy(&buf);
158       return retval; }
159     sum += length;
160     retval = asn1_make_etag(buf,CONTEXT_SPECIFIC,8,length,&length);
161     if(retval){
162       asn1buf_destroy(&buf);
163       return retval; }
164     sum += length;
165   }
166
167   /* seq-number[7]              INTEGER OPTIONAL */
168   if(rep->seq_number != 0)
169     krb5_addfield(rep->seq_number,7,asn1_encode_integer);
170
171   /* subkey[6]                  EncryptionKey OPTIONAL */
172   if(rep->subkey != NULL)
173     krb5_addfield(rep->subkey,6,asn1_encode_encryption_key);
174
175   /* ctime[5]                   KerberosTime */
176   krb5_addfield(rep->ctime,5,asn1_encode_kerberos_time);
177
178   /* cusec[4]                   INTEGER */
179   krb5_addfield(rep->cusec,4,asn1_encode_integer);
180
181   /* cksum[3]                   Checksum OPTIONAL */
182   if(rep->checksum != NULL)
183     krb5_addfield(rep->checksum,3,asn1_encode_checksum);
184
185   /* cname[2]                   PrincipalName */
186   krb5_addfield(rep->client,2,asn1_encode_principal_name);
187
188   /* crealm[1]                  Realm */
189   krb5_addfield(rep->client,1,asn1_encode_realm);
190
191   /* authenticator-vno[0]       INTEGER */
192   krb5_addfield(KVNO,0,asn1_encode_integer);
193
194   /* Authenticator ::= [APPLICATION 2] SEQUENCE */
195   krb5_makeseq();
196   krb5_apptag(2);
197
198   krb5_cleanup();
199 }
200
201 krb5_error_code INTERFACE encode_krb5_ticket(rep, code)
202      const krb5_ticket * rep;
203      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 INTERFACE encode_krb5_encryption_key(rep, code)
227      const krb5_keyblock * rep;
228      krb5_data ** code;
229 {
230   krb5_setup();
231
232   /* keyvalue[1]        OCTET STRING */
233   krb5_addlenfield(rep->length,rep->contents,1,asn1_encode_octetstring);
234
235   /* keytype[0]         INTEGER */
236   krb5_addfield(rep->keytype,0,asn1_encode_integer);
237
238   /* EncryptionKey ::= SEQUENCE */
239   krb5_makeseq();
240
241   krb5_cleanup();
242 }
243
244 krb5_error_code INTERFACE encode_krb5_enc_tkt_part(rep, code)
245      const krb5_enc_tkt_part * rep;
246      krb5_data ** code;
247 {
248   krb5_setup();
249
250   /* authorization-data[10]     AuthorizationData OPTIONAL */
251   if(rep->authorization_data != NULL &&
252      rep->authorization_data[0] != NULL)
253     krb5_addfield((const krb5_authdata**)rep->authorization_data,
254                   10,asn1_encode_authorization_data);
255
256   /* caddr[9]                   HostAddresses OPTIONAL */
257   if(rep->caddrs != NULL && rep->caddrs[0] != NULL)
258     krb5_addfield((const krb5_address**)rep->caddrs,9,asn1_encode_host_addresses);
259
260   /* renew-till[8]              KerberosTime OPTIONAL */
261   if(rep->times.renew_till)
262     krb5_addfield(rep->times.renew_till,8,asn1_encode_kerberos_time);
263
264   /* endtime[7]                 KerberosTime */
265   krb5_addfield(rep->times.endtime,7,asn1_encode_kerberos_time);
266
267   /* starttime[6]               KerberosTime OPTIONAL */
268   if(rep->times.starttime)
269     krb5_addfield(rep->times.starttime,6,asn1_encode_kerberos_time);
270
271   /* authtime[5]                KerberosTime */
272   krb5_addfield(rep->times.authtime,5,asn1_encode_kerberos_time);
273
274   /* transited[4]               TransitedEncoding */
275   krb5_addfield(&(rep->transited),4,asn1_encode_transited_encoding);
276
277   /* cname[3]                   PrincipalName */
278   krb5_addfield(rep->client,3,asn1_encode_principal_name);
279
280   /* crealm[2]                  Realm */
281   krb5_addfield(rep->client,2,asn1_encode_realm);
282
283   /* key[1]                     EncryptionKey */
284   krb5_addfield(rep->session,1,asn1_encode_encryption_key);
285
286   /* flags[0]                   TicketFlags */
287   krb5_addfield(rep->flags,0,asn1_encode_ticket_flags);
288
289   /* EncTicketPart ::= [APPLICATION 3] SEQUENCE */
290   krb5_makeseq();
291   krb5_apptag(3);
292
293   krb5_cleanup();
294 }
295
296 krb5_error_code INTERFACE encode_krb5_enc_kdc_rep_part(rep, code)
297      const krb5_enc_kdc_rep_part * rep;
298      krb5_data ** code;
299 {
300   asn1_error_code retval;
301   asn1buf *buf=NULL;
302   int length, sum=0;
303
304   if(rep == NULL) return ASN1_MISSING_FIELD;
305
306   retval = asn1buf_create(&buf);
307   if(retval) return retval;
308
309   retval = asn1_encode_enc_kdc_rep_part(buf,rep,&length);
310   if(retval) return retval;
311   sum += length;
312
313 #ifdef KRB5_ENCKRB5KDCREPPART_COMPAT
314   krb5_apptag(26);
315 #else
316   if (rep->msg_type == KRB5_AS_REP) { krb5_apptag(ASN1_KRB_AS_REP); }
317   else if (rep->msg_type == KRB5_TGS_REP) { krb5_apptag(ASN1_KRB_TGS_REP); }
318   else return KRB5_BADMSGTYPE;
319 #endif
320   krb5_cleanup();
321 }
322
323 /* yes, the translation is identical to that used for KDC__REP */ 
324 krb5_error_code INTERFACE encode_krb5_as_rep(rep, code)
325      const krb5_kdc_rep * rep;
326      krb5_data ** code;
327 {
328   krb5_setup();
329
330   /* AS-REP ::= [APPLICATION 11] KDC-REP */
331   retval = asn1_encode_kdc_rep(KRB5_AS_REP,buf,rep,&length);
332   if(retval) return retval;
333   sum += length;
334
335   krb5_apptag(11);
336
337   krb5_cleanup();
338 }
339
340 /* yes, the translation is identical to that used for KDC__REP */ 
341 krb5_error_code INTERFACE encode_krb5_tgs_rep( rep, code)
342      const krb5_kdc_rep * rep;
343      krb5_data ** code;
344 {
345   krb5_setup();
346
347   /* TGS-REP ::= [APPLICATION 13] KDC-REP */
348   retval = asn1_encode_kdc_rep(KRB5_TGS_REP,buf,rep,&length);
349   if(retval) return retval;
350   sum += length;
351
352   krb5_apptag(13);
353
354   krb5_cleanup();
355 }
356
357 krb5_error_code INTERFACE encode_krb5_ap_req(rep, code)
358      const krb5_ap_req * rep;
359      krb5_data ** code;
360 {
361   krb5_setup();
362
363   /* authenticator[4]   EncryptedData */
364   krb5_addfield(&(rep->authenticator),4,asn1_encode_encrypted_data);
365
366   /* ticket[3]          Ticket */
367   krb5_addfield(rep->ticket,3,asn1_encode_ticket);
368
369   /* ap-options[2]      APOptions */
370   krb5_addfield(rep->ap_options,2,asn1_encode_ap_options);
371
372   /* msg-type[1]        INTEGER */
373   krb5_addfield(ASN1_KRB_AP_REQ,1,asn1_encode_integer);
374
375   /* pvno[0]            INTEGER */
376   krb5_addfield(KVNO,0,asn1_encode_integer);
377
378   /* AP-REQ ::= [APPLICATION 14] SEQUENCE */
379   krb5_makeseq();
380   krb5_apptag(14);
381
382   krb5_cleanup();
383 }
384
385 krb5_error_code INTERFACE encode_krb5_ap_rep(rep, code)
386      const krb5_ap_rep * rep;
387      krb5_data ** code;
388 {
389   krb5_setup();
390
391   /* enc-part[2]        EncryptedData */
392   krb5_addfield(&(rep->enc_part),2,asn1_encode_encrypted_data);
393   
394   /* msg-type[1]        INTEGER */
395   krb5_addfield(ASN1_KRB_AP_REP,1,asn1_encode_integer);
396   
397   /* pvno[0]            INTEGER */
398   krb5_addfield(KVNO,0,asn1_encode_integer);
399   
400   /* AP-REP ::= [APPLICATION 15] SEQUENCE */
401   krb5_makeseq();
402   krb5_apptag(15);
403   
404   krb5_cleanup();
405 }
406
407
408 krb5_error_code INTERFACE encode_krb5_ap_rep_enc_part(rep, code)
409      const krb5_ap_rep_enc_part * rep;
410      krb5_data ** code;
411 {
412   krb5_setup();
413
414   /* seq-number[3]      INTEGER OPTIONAL */
415   if(rep->seq_number)
416     krb5_addfield(rep->seq_number,3,asn1_encode_integer);
417
418   /* subkey[2]          EncryptionKey OPTIONAL */
419   if(rep->subkey != NULL)
420     krb5_addfield(rep->subkey,2,asn1_encode_encryption_key);
421
422   /* cusec[1]           INTEGER */
423   krb5_addfield(rep->cusec,1,asn1_encode_integer);
424
425   /* ctime[0]           KerberosTime */
426   krb5_addfield(rep->ctime,0,asn1_encode_kerberos_time);
427
428   /* EncAPRepPart ::= [APPLICATION 27] SEQUENCE */
429   krb5_makeseq();
430   krb5_apptag(27);
431
432   krb5_cleanup();
433 }
434
435 krb5_error_code INTERFACE encode_krb5_as_req(rep, code)
436      const krb5_kdc_req * rep;
437      krb5_data ** code;
438 {
439   krb5_setup();
440
441   /* AS-REQ ::= [APPLICATION 10] KDC-REQ */
442   retval = asn1_encode_kdc_req(KRB5_AS_REQ,buf,rep,&length);
443   if(retval) return retval;
444   sum += length;
445
446   krb5_apptag(10);
447
448   krb5_cleanup();
449 }
450
451 krb5_error_code INTERFACE encode_krb5_tgs_req(rep, code)
452      const krb5_kdc_req * rep;
453      krb5_data ** code;
454 {
455   krb5_setup();
456
457   /* TGS-REQ ::= [APPLICATION 12] KDC-REQ */
458   retval = asn1_encode_kdc_req(KRB5_TGS_REQ,buf,rep,&length);
459   if(retval) return retval;
460   sum += length;
461
462   krb5_apptag(12);
463
464   krb5_cleanup();
465 }
466
467 krb5_error_code INTERFACE encode_krb5_kdc_req_body(rep, code)
468      const krb5_kdc_req * rep;
469      krb5_data ** code;
470 {
471   krb5_setup();
472
473   retval = asn1_encode_kdc_req_body(buf,rep,&length);
474   if(retval) return retval;
475   sum += length;
476
477   krb5_cleanup();
478 }
479
480
481 krb5_error_code INTERFACE encode_krb5_safe(rep, code)
482      const krb5_safe * rep;
483      krb5_data ** code;
484 {
485   krb5_setup();
486
487   /* cksum[3]           Checksum */
488   krb5_addfield(rep->checksum,3,asn1_encode_checksum);
489
490   /* safe-body[2]       KRB-SAFE-BODY */
491   krb5_addfield(rep,2,asn1_encode_krb_safe_body);
492
493   /* msg-type[1]        INTEGER */
494   krb5_addfield(ASN1_KRB_SAFE,1,asn1_encode_integer);
495
496   /* pvno[0]            INTEGER */
497   krb5_addfield(KVNO,0,asn1_encode_integer);
498
499   /* KRB-SAFE ::= [APPLICATION 20] SEQUENCE */
500   krb5_makeseq();
501   krb5_apptag(20);
502
503   krb5_cleanup();
504 }
505
506 krb5_error_code INTERFACE encode_krb5_priv(rep, code)
507      const krb5_priv * rep;
508      krb5_data ** code;
509 {
510   krb5_setup();
511
512   /* enc-part[3]        EncryptedData */
513   krb5_addfield(&(rep->enc_part),3,asn1_encode_encrypted_data);
514
515   /* msg-type[1]        INTEGER */
516   krb5_addfield(ASN1_KRB_PRIV,1,asn1_encode_integer);
517
518   /* pvno[0]            INTEGER */
519   krb5_addfield(KVNO,0,asn1_encode_integer);
520
521   /* KRB-PRIV ::= [APPLICATION 21] SEQUENCE */
522   krb5_makeseq();
523   krb5_apptag(21);
524
525   krb5_cleanup();
526 }
527
528 krb5_error_code INTERFACE encode_krb5_enc_priv_part(rep, code)
529      const krb5_priv_enc_part * rep;
530      krb5_data ** code;
531 {
532   krb5_setup();
533
534   /* r-address[5]       HostAddress OPTIONAL -- recip's addr */
535   if(rep->r_address)
536     krb5_addfield(rep->r_address,5,asn1_encode_host_address);
537
538   /* s-address[4]       HostAddress -- sender's addr */
539   krb5_addfield(rep->s_address,4,asn1_encode_host_address);
540
541   /* seq-number[3]      INTEGER OPTIONAL */
542   if(rep->seq_number)
543     krb5_addfield(rep->seq_number,3,asn1_encode_integer);
544
545   /* usec[2]            INTEGER OPTIONAL */
546   if(rep->timestamp){
547     krb5_addfield(rep->usec,2,asn1_encode_integer);
548     /* timestamp[1]     KerberosTime OPTIONAL */
549     krb5_addfield(rep->timestamp,1,asn1_encode_kerberos_time);
550   }
551
552   /* user-data[0]       OCTET STRING */
553   krb5_addlenfield(rep->user_data.length,rep->user_data.data,0,asn1_encode_charstring);
554
555   /* EncKrbPrivPart ::= [APPLICATION 28] SEQUENCE */
556   krb5_makeseq();
557   krb5_apptag(28);
558
559   krb5_cleanup();
560 }
561
562 krb5_error_code INTERFACE encode_krb5_cred(rep, code)
563      const krb5_cred * rep;
564      krb5_data ** code;
565 {
566   krb5_setup();
567
568   /* enc-part[3]        EncryptedData */
569   krb5_addfield(&(rep->enc_part),3,asn1_encode_encrypted_data);
570
571   /* tickets[2]         SEQUENCE OF Ticket */
572   krb5_addfield((const krb5_ticket**)rep->tickets,2,asn1_encode_sequence_of_ticket);
573
574   /* msg-type[1]        INTEGER, -- KRB_CRED */
575   krb5_addfield(ASN1_KRB_CRED,1,asn1_encode_integer);
576
577   /* pvno[0]            INTEGER */
578   krb5_addfield(KVNO,0,asn1_encode_integer);
579
580   /* KRB-CRED ::= [APPLICATION 22] SEQUENCE */
581   krb5_makeseq();
582   krb5_apptag(22);
583
584   krb5_cleanup();
585 }
586
587 krb5_error_code INTERFACE encode_krb5_enc_cred_part(rep, code)
588      const krb5_cred_enc_part * rep;
589      krb5_data ** code;
590 {
591   krb5_setup();
592
593   /* r-address[5]       HostAddress OPTIONAL */
594   if(rep->r_address != NULL)
595     krb5_addfield(rep->r_address,5,asn1_encode_host_address);
596
597   /* s-address[4]       HostAddress OPTIONAL */
598   if(rep->s_address != NULL)
599     krb5_addfield(rep->s_address,4,asn1_encode_host_address);
600
601   /* usec[3]            INTEGER OPTIONAL */
602   if(rep->timestamp){
603     krb5_addfield(rep->usec,3,asn1_encode_integer);
604     /* timestamp[2]     KerberosTime OPTIONAL */
605     krb5_addfield(rep->timestamp,2,asn1_encode_kerberos_time);
606   }
607
608   /* nonce[1]           INTEGER OPTIONAL */
609   if(rep->nonce)
610     krb5_addfield(rep->nonce,1,asn1_encode_integer);
611
612   /* ticket-info[0]     SEQUENCE OF KrbCredInfo */
613   krb5_addfield((const krb5_cred_info**)rep->ticket_info,
614                 0,asn1_encode_sequence_of_krb_cred_info);
615
616   /* EncKrbCredPart ::= [APPLICATION 29] SEQUENCE */
617   krb5_makeseq();
618   krb5_apptag(29);
619
620   krb5_cleanup();
621 }
622
623 krb5_error_code INTERFACE encode_krb5_error(rep, code)
624      const krb5_error * rep;
625      krb5_data ** code;
626 {
627   krb5_setup();
628
629   /* e-data[12]         OCTET STRING OPTIONAL */
630   if(rep->e_data.data != NULL && rep->e_data.length > 0)
631     krb5_addlenfield(rep->e_data.length,rep->e_data.data,12,asn1_encode_charstring);
632
633   /* e-text[11]         GeneralString OPTIONAL */
634   if(rep->text.data != NULL && rep->text.length > 0)
635     krb5_addlenfield(rep->text.length,rep->text.data,11,asn1_encode_generalstring);
636
637   /* sname[10]          PrincipalName -- Correct name */
638   krb5_addfield(rep->server,10,asn1_encode_principal_name);
639
640   /* realm[9]           Realm -- Correct realm */
641   krb5_addfield(rep->server,9,asn1_encode_realm);
642
643   /* cname[8]           PrincipalName OPTIONAL */
644   if(rep->client != NULL){
645     krb5_addfield(rep->client,8,asn1_encode_principal_name);
646     /* crealm[7]                Realm OPTIONAL */
647     krb5_addfield(rep->client,7,asn1_encode_realm);
648   }
649
650   /* error-code[6]      INTEGER */
651   krb5_addfield(rep->error,6,asn1_encode_ui_4);
652
653   /* susec[5]           INTEGER */
654   krb5_addfield(rep->susec,5,asn1_encode_integer);
655
656   /* stime[4]           KerberosTime */
657   krb5_addfield(rep->stime,4,asn1_encode_kerberos_time);
658
659   /* cusec[3]           INTEGER OPTIONAL */
660   if(rep->cusec)
661     krb5_addfield(rep->cusec,3,asn1_encode_integer);
662
663   /* ctime[2]           KerberosTime OPTIONAL */
664   if(rep->ctime)
665     krb5_addfield(rep->ctime,2,asn1_encode_kerberos_time);
666
667   /* msg-type[1]        INTEGER */
668   krb5_addfield(ASN1_KRB_ERROR,1,asn1_encode_integer);
669
670   /* pvno[0]            INTEGER */
671   krb5_addfield(KVNO,0,asn1_encode_integer);
672
673   /* KRB-ERROR ::= [APPLICATION 30] SEQUENCE */
674   krb5_makeseq();
675   krb5_apptag(30);
676
677   krb5_cleanup();
678 }
679
680 krb5_error_code INTERFACE encode_krb5_authdata(rep, code)
681      const krb5_authdata ** rep;
682      krb5_data ** code;
683 {
684   asn1_error_code retval;
685   asn1buf *buf=NULL;
686   int length;
687   
688   if(rep == NULL) return ASN1_MISSING_FIELD;
689
690   retval = asn1buf_create(&buf);
691   if(retval) return retval;
692
693   retval = asn1_encode_authorization_data(buf,(const krb5_authdata**)rep,
694                                           &length);
695   if(retval) return retval;
696
697   krb5_cleanup();
698 }
699
700 /* Sandia Additions */
701 krb5_error_code INTERFACE encode_krb5_pwd_sequence( rep, code)
702      const passwd_phrase_element * rep;
703      krb5_data ** code;
704 {
705   krb5_setup();
706   retval = asn1_encode_passwdsequence(buf,rep,&length);
707   if(retval) return retval;
708   sum += length;
709   krb5_cleanup();
710 }
711
712 krb5_error_code INTERFACE encode_krb5_pwd_data(rep, code)
713      const krb5_pwd_data * rep;
714      krb5_data ** code;
715 {
716   krb5_setup();
717   krb5_addfield((const passwd_phrase_element**)rep->element,1,asn1_encode_sequence_of_passwdsequence);
718   krb5_addfield(rep->sequence_count,0,asn1_encode_integer);
719   krb5_makeseq();
720   krb5_cleanup();
721 }