1 /* 2 * src/lib/krb5/asn.1/asn1_make.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. Furthermore if you modify this software you must label 20 * your software as modified software and not distribute it in such a 21 * fashion that it might be confused with the original M.I.T. software. 22 * M.I.T. makes no representations about the suitability of 23 * this software for any purpose. It is provided "as is" without express 24 * or implied warranty. 25 */ 26 27 #include "asn1_make.h" 28 29 asn1_error_code asn1_make_etag(asn1buf *buf, asn1_class asn1class, 30 asn1_tagnum tagnum, unsigned int in_len, 31 unsigned int *retlen) 32 { 33 return asn1_make_tag(buf,asn1class,CONSTRUCTED,tagnum,in_len,retlen); 34 } 35 36 37 asn1_error_code asn1_make_tag(asn1buf *buf, asn1_class asn1class, 38 asn1_construction construction, 39 asn1_tagnum tagnum, unsigned int in_len, 40 unsigned int *retlen) 41 { 42 asn1_error_code retval; 43 unsigned int sumlen=0, length; 44 45 if(tagnum > ASN1_TAGNUM_MAX) return ASN1_OVERFLOW; 46 47 retval = asn1_make_length(buf,in_len, &length); 48 if(retval) return retval; 49 sumlen += length; 50 retval = asn1_make_id(buf,asn1class,construction,tagnum,&length); 51 if(retval) return retval; 52 sumlen += length; 53 54 *retlen = sumlen; 55 return 0; 56 } 57 58 asn1_error_code asn1_make_length(asn1buf *buf, const unsigned int in_len, unsigned int *retlen) 59 { 60 asn1_error_code retval; 61 62 if(in_len < 128){ 63 retval = asn1buf_insert_octet(buf, (asn1_octet)(in_len&0x7F)); 64 if(retval) return retval; 65 *retlen = 1; 66 }else{ 67 int in_copy=in_len, length=0; 68 69 while(in_copy != 0){ 70 retval = asn1buf_insert_octet(buf, (asn1_octet)(in_copy&0xFF)); 71 if(retval) return retval; 72 in_copy = in_copy >> 8; 73 length++; 74 } 75 retval = asn1buf_insert_octet(buf, (asn1_octet) (0x80 | (asn1_octet)(length&0x7F))); 76 if(retval) return retval; 77 length++; 78 *retlen = length; 79 } 80 81 return 0; 82 } 83 84 asn1_error_code asn1_make_id(asn1buf *buf, asn1_class asn1class, 85 asn1_construction construction, 86 asn1_tagnum tagnum, unsigned int *retlen) 87 { 88 asn1_error_code retval; 89 90 if(tagnum < 31) { 91 retval = asn1buf_insert_octet(buf, (asn1_octet) (asn1class | construction | 92 (asn1_octet)tagnum)); 93 if(retval) return retval; 94 *retlen = 1; 95 }else{ 96 asn1_tagnum tagcopy = tagnum; 97 int length = 0; 98 99 retval = asn1buf_insert_octet(buf, (asn1_octet)(tagcopy&0x7F)); 100 if(retval) return retval; 101 tagcopy >>= 7; 102 length++; 103 104 for(; tagcopy != 0; tagcopy >>= 7){ 105 retval = asn1buf_insert_octet(buf, (asn1_octet) (0x80 | (asn1_octet)(tagcopy&0x7F))); 106 if(retval) return retval; 107 length++; 108 } 109 110 retval = asn1buf_insert_octet(buf, (asn1_octet) (asn1class | construction | 0x1F)); 111 if(retval) return retval; 112 length++; 113 *retlen = length; 114 } 115 116 return 0; 117 } 118 119 asn1_error_code asn1_make_sequence(asn1buf *buf, const unsigned int seq_len, unsigned int *retlen) 120 { 121 asn1_error_code retval; 122 unsigned int len, sum=0; 123 124 retval = asn1_make_length(buf,seq_len,&len); 125 if(retval) return retval; 126 sum += len; 127 retval = asn1_make_id(buf,UNIVERSAL,CONSTRUCTED,ASN1_SEQUENCE,&len); 128 if(retval) return retval; 129 sum += len; 130 131 *retlen = sum; 132 return 0; 133 } 134 135 asn1_error_code asn1_make_set(asn1buf *buf, const unsigned int set_len, unsigned int *retlen) 136 { 137 asn1_error_code retval; 138 unsigned int len, sum=0; 139 140 retval = asn1_make_length(buf,set_len,&len); 141 if(retval) return retval; 142 sum += len; 143 retval = asn1_make_id(buf,UNIVERSAL,CONSTRUCTED,ASN1_SET,&len); 144 if(retval) return retval; 145 sum += len; 146 147 *retlen = sum; 148 return 0; 149 } 150 151 asn1_error_code asn1_make_string(asn1buf *buf, const unsigned int length, const char *string, int *retlen) 152 { 153 asn1_error_code retval; 154 155 retval = asn1buf_insert_charstring(buf,length,string); 156 if(retval) return retval; 157 158 *retlen = length; 159 return 0; 160 } 161