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 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 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 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 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 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 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 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