1 #pragma ident "%Z%%M% %I% %E% SMI"
2
3 /*
4 * src/lib/krb5/asn.1/asn1_make.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 "asn1_make.h"
30
asn1_make_etag(asn1buf * buf,asn1_class asn1class,asn1_tagnum tagnum,unsigned int in_len,unsigned int * retlen)31 asn1_error_code asn1_make_etag(asn1buf *buf, asn1_class asn1class,
32 asn1_tagnum tagnum, unsigned int in_len,
33 unsigned int *retlen)
34 {
35 return asn1_make_tag(buf,asn1class,CONSTRUCTED,tagnum,in_len,retlen);
36 }
37
38
asn1_make_tag(asn1buf * buf,asn1_class asn1class,asn1_construction construction,asn1_tagnum tagnum,unsigned int in_len,unsigned int * retlen)39 asn1_error_code asn1_make_tag(asn1buf *buf, asn1_class asn1class,
40 asn1_construction construction,
41 asn1_tagnum tagnum, unsigned int in_len,
42 unsigned int *retlen)
43 {
44 asn1_error_code retval;
45 unsigned int sumlen=0, length;
46
47 if(tagnum > ASN1_TAGNUM_MAX) return ASN1_OVERFLOW;
48
49 retval = asn1_make_length(buf,in_len, &length);
50 if(retval) return retval;
51 sumlen += length;
52 retval = asn1_make_id(buf,asn1class,construction,tagnum,&length);
53 if(retval) return retval;
54 sumlen += length;
55
56 *retlen = sumlen;
57 return 0;
58 }
59
asn1_make_length(asn1buf * buf,const unsigned int in_len,unsigned int * retlen)60 asn1_error_code asn1_make_length(asn1buf *buf, const unsigned int in_len, unsigned int *retlen)
61 {
62 asn1_error_code retval;
63
64 if(in_len < 128){
65 retval = asn1buf_insert_octet(buf, (asn1_octet)(in_len&0x7F));
66 if(retval) return retval;
67 *retlen = 1;
68 }else{
69 int in_copy=in_len, length=0;
70
71 while(in_copy != 0){
72 retval = asn1buf_insert_octet(buf, (asn1_octet)(in_copy&0xFF));
73 if(retval) return retval;
74 in_copy = in_copy >> 8;
75 length++;
76 }
77 retval = asn1buf_insert_octet(buf, (asn1_octet) (0x80 | (asn1_octet)(length&0x7F)));
78 if(retval) return retval;
79 length++;
80 *retlen = length;
81 }
82
83 return 0;
84 }
85
asn1_make_id(asn1buf * buf,asn1_class asn1class,asn1_construction construction,asn1_tagnum tagnum,unsigned int * retlen)86 asn1_error_code asn1_make_id(asn1buf *buf, asn1_class asn1class,
87 asn1_construction construction,
88 asn1_tagnum tagnum, unsigned int *retlen)
89 {
90 asn1_error_code retval;
91
92 if(tagnum < 31) {
93 retval = asn1buf_insert_octet(buf, (asn1_octet) (asn1class | construction |
94 (asn1_octet)tagnum));
95 if(retval) return retval;
96 *retlen = 1;
97 }else{
98 asn1_tagnum tagcopy = tagnum;
99 int length = 0;
100
101 retval = asn1buf_insert_octet(buf, (asn1_octet)(tagcopy&0x7F));
102 if(retval) return retval;
103 tagcopy >>= 7;
104 length++;
105
106 for(; tagcopy != 0; tagcopy >>= 7){
107 retval = asn1buf_insert_octet(buf, (asn1_octet) (0x80 | (asn1_octet)(tagcopy&0x7F)));
108 if(retval) return retval;
109 length++;
110 }
111
112 retval = asn1buf_insert_octet(buf, (asn1_octet) (asn1class | construction | 0x1F));
113 if(retval) return retval;
114 length++;
115 *retlen = length;
116 }
117
118 return 0;
119 }
120
asn1_make_sequence(asn1buf * buf,const unsigned int seq_len,unsigned int * retlen)121 asn1_error_code asn1_make_sequence(asn1buf *buf, const unsigned int seq_len, unsigned int *retlen)
122 {
123 asn1_error_code retval;
124 unsigned int len, sum=0;
125
126 retval = asn1_make_length(buf,seq_len,&len);
127 if(retval) return retval;
128 sum += len;
129 retval = asn1_make_id(buf,UNIVERSAL,CONSTRUCTED,ASN1_SEQUENCE,&len);
130 if(retval) return retval;
131 sum += len;
132
133 *retlen = sum;
134 return 0;
135 }
136
asn1_make_set(asn1buf * buf,const unsigned int set_len,unsigned int * retlen)137 asn1_error_code asn1_make_set(asn1buf *buf, const unsigned int set_len, unsigned int *retlen)
138 {
139 asn1_error_code retval;
140 unsigned int len, sum=0;
141
142 retval = asn1_make_length(buf,set_len,&len);
143 if(retval) return retval;
144 sum += len;
145 retval = asn1_make_id(buf,UNIVERSAL,CONSTRUCTED,ASN1_SET,&len);
146 if(retval) return retval;
147 sum += len;
148
149 *retlen = sum;
150 return 0;
151 }
152
asn1_make_string(asn1buf * buf,const unsigned int length,const char * string,int * retlen)153 asn1_error_code asn1_make_string(asn1buf *buf, const unsigned int length, const char *string, int *retlen)
154 {
155 asn1_error_code retval;
156
157 retval = asn1buf_insert_charstring(buf,length,string);
158 if(retval) return retval;
159
160 *retlen = length;
161 return 0;
162 }
163